【C#】【xUnit】【Moq】.NET单元测试Mock框架Moq初探!

简介: 在TDD开发模型中,经常是在编码的同时进行单元测试的编写,由于现代软件开发不可能是一个人完成的工作,所以在定义好接口的时候我们就可以进行自己功能的开发(接口不能经常变更),而我们调用他人的功能时只需要使用接口即可。

在TDD开发模型中,经常是在编码的同时进行单元测试的编写,由于现代软件开发不可能是一个人完成的工作,所以在定义好接口的时候我们就可以进行自己功能的开发(接口不能经常变更),而我们调用他人的功能时只需要使用接口即可。
但我们在编写自己的单元测试并进行功能验证的时候,如果接口的实现人还没有完成代码怎么办呢?一般我们可能会自己写一个模拟实现来进行单元测试,这就是我们经常所说的单元测试中的Stub和Mock(关于单元测试的Stub和Mock,可以自己度娘一下,也可以参考https://www.cnblogs.com/TankXiao/archive/2012/03/06/2366073.html, 本文的部分代码来自于这篇博客)。在.net环境中可以使用的Mock框架是Moq,目前版本4.10。
我们使用NuGet安装依赖的库xUnit,Moq等。
我们定义两个接口:

    public interface IWebService
    {
        void LogError(string msg);
    }

    public interface IEmailService
    {
        void SendEmail(string a, string b, string c, string d);
    }

一个类:

    public class LogAnalyzer
    {
        private IWebService service;
        private IEmailService email;

        public IWebService Service
        {
            get { return service; }
            set { service = value; }
        }

        public IEmailService Email
        {
            get { return email; }
            set { email = value; }
        }

        public void Analyze(string fileName)
        {
            if (fileName.Length < 8)
            {
                try
                {
                    service.LogError("the file name is to short" + fileName);
                }
                catch (Exception e)
                {
                    email.SendEmail("From@test.com", "To@test.com", "IWebServiceFailed", e.Message);
                }
            }
        }
    }

我们要进行这个类的测试,其中两个接口的实现是别人来做。我在自己的单元测试中不想去引用他人的实现,也不想自己写Mock,所以使用框架Moq来创建我想要的对象。

public class LogAnalyzerTest
    {
        [Fact(DisplayName = "使用MOQ框架")]
        public void AnalyzeTest()
        {
            var mockWebService = new Mock<IWebService>();
            mockWebService.Setup(p => p.LogError(It.Is<string>(str => str.Length > 8))).Throws(new Exception());
            var mockEmailService = new Mock<IEmailService>();
            var a = mockEmailService.Setup(e => e.SendEmail("From@test.com", "To@test.com", "IWebServiceFailed", It.Is<string>(x=>x != null)));
            LogAnalyzer log = new LogAnalyzer();
            log.Service = mockWebService.Object;
            log.Email = mockEmailService.Object;
            log.Analyze("xxx");
            mockEmailService.Verify(p => p.SendEmail("From@test.com", "To@test.com", "IWebServiceFailed", It.Is<string>(x => x != null)));
        }
    }

这样我就完成了我的单元测试,而不用去关心我的依赖的代码的实现。保证我的功能的正确性。
对上面Mock的说明如下:
第一个模拟LogError抛出异常的代码:

            mockWebService.Setup(p => p.LogError(It.Is<string>(str => str.Length > 8))).Throws(new Exception());

第一行,当参数类型是string且长度大于8时正常执行,而长度长于等于8时则抛出异常。他的另一种写法是范型:

            mockWebService.Setup(p => p.LogError(It.Is<string>(str => str.Length > 8))).Throws<Exception>();

在我调用分析方法Analyze时传入的字符串不长于8个,就会完成异常抛出异常的功能。
第二个是Email接口的Mock对象,创建如下:

            var a = mockEmailService.Setup(e => e.SendEmail("From@test.com", "To@test.com", "IWebServiceFailed", It.Is<string>(x=>x != null)));

因为最后一个参数是异常的Message,所以我们需要动态指定。前三个参数和代码中一致。
最后验证SendEmail有没有执行。这行代码不能放在log.Analyze调用之前。因为这个时候方法还没有调用,单元测试不会通过。并且参数保持一致。如果参数不一致(特别是前三个)也会测试失败。这就是Mock的强大之处。

你的支持是我继续的动力啊。
123

目录
相关文章
|
3天前
|
Web App开发 敏捷开发 数据管理
自动化测试框架的设计与实现
【9月更文挑战第32天】在软件开发的海洋中,自动化测试如同一艘精确导航的船只,确保我们的应用程序能够在波涛汹涌的技术潮流中稳健航行。本文将带你领略自动化测试框架的设计之美,从搭建基础到功能扩展,再到维护实践,我们将一起探索如何打造一个既高效又灵活的自动化测试体系。
|
19天前
|
敏捷开发 IDE 测试技术
自动化测试框架的选择与应用
【9月更文挑战第16天】在软件开发周期中,测试环节扮演着至关重要的角色。随着敏捷开发和持续集成的流行,自动化测试成为提升软件质量和效率的关键手段。本文将探讨如何根据项目需求选择合适的自动化测试框架,并通过实际案例分析展示其在软件开发过程中的应用。我们将从单元测试、集成测试到端到端测试等多个层面,讨论自动化测试的最佳实践和常见问题解决策略。
|
9天前
|
敏捷开发 Java 测试技术
自动化测试框架的选择与应用
【9月更文挑战第26天】在软件开发的海洋里,自动化测试是那一盏指路明灯。它不仅加快了开发周期,还提升了软件质量。本文将带你探索自动化测试框架的世界,了解它们的核心特性、适用场景及如何根据项目需求做出明智选择。让我们一起启航,找到那把打开高效、稳定软件生产大门的钥匙。
|
13天前
|
测试技术 数据库连接 数据库
提升软件测试效率与灵活性:探索Mock测试的重要性
【9月更文挑战第20天】在软件测试领域,提升测试效率与灵活性至关重要。Mock 测试通过模拟外部组件,使模块能独立测试,缩短测试周期;快速反馈机制让测试结果即时可见,加速问题修复;还能模拟异常情况和进行参数化测试,增强测试全面性与灵活性,从而显著提高软件质量和开发效率。
|
9天前
|
敏捷开发 数据管理 测试技术
自动化测试框架的设计与实现
【9月更文挑战第25天】 本文将引导读者深入理解自动化测试框架的核心概念,并展示如何从零开始构建一个简单且有效的自动化测试框架。通过通俗易懂的语言和实际代码示例,我们将探讨测试框架设计的关键步骤、实现方法以及常见问题的解决方案。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的知识和启示。
|
15天前
|
编译器 C# Android开发
Uno Platform 是一个用于构建跨平台应用程序的强大框架,它允许开发者使用 C# 和 XAML 来创建适用于多个平台的应用
Uno Platform 是一个用于构建跨平台应用程序的强大框架,它允许开发者使用 C# 和 XAML 来创建适用于多个平台的应用
50 8
|
11天前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
|
9天前
|
设计模式 测试技术 持续交付
自动化测试框架的设计与实现
【9月更文挑战第25天】本文旨在探讨如何设计并实现一个高效、可扩展的自动化测试框架,以提升软件测试的效率和质量。通过分析当前流行的测试框架特点,结合最佳实践,提出一套完整的解决方案。文章不仅涵盖框架设计的理论依据,还包括具体实现步骤和示例,帮助读者深入理解自动化测试框架的搭建过程。
|
5月前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
169 3
|
5月前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
181 3
下一篇
无影云桌面