【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

目录
相关文章
|
6天前
|
开发框架 前端开发 .NET
LIMS(实验室)信息管理系统源码、有哪些应用领域?采用C# ASP.NET dotnet 3.5 开发的一套实验室信息系统源码
集成于VS 2019,EXT.NET前端和ASP.NET后端,搭配MSSQL 2018数据库。系统覆盖样品管理、数据分析、报表和项目管理等实验室全流程。应用广泛,包括生产质检(如石化、制药)、环保监测、试验研究等领域。随着技术发展,现代LIMS还融合了临床、电子实验室笔记本和SaaS等功能,以满足复杂多样的实验室管理需求。
16 3
LIMS(实验室)信息管理系统源码、有哪些应用领域?采用C# ASP.NET dotnet 3.5 开发的一套实验室信息系统源码
|
5天前
|
Java C# 数据安全/隐私保护
|
12天前
|
Cloud Native API C#
C#的现代化:.NET Core引领的技术革命
【6月更文挑战第9天】`.NET Core引领C#现代化,实现跨平台革命,提升性能并支持云原生应用。异步编程模型优化体验,统一API简化开发流程。C#应用场景扩展,开发效率提高,技术创新加速,预示其未来在技术领域将持续发挥关键作用。`
28 10
|
10天前
|
存储 编解码 算法
C#.NET逃逸时间算法生成分形图像的毕业设计完成!晒晒功能
该文介绍了一个使用C#.NET Visual Studio 2008开发的程序,包含错误修复的Julia、Mandelbrot和优化过的Newton三种算法,生成色彩丰富的分形图像。作者改进了原始算法的效率,将内层循环的画点操作移至外部,提升性能。程序提供五种图形模式,支持放大缩小及颜色更新,并允许用户自定义画布大小以调整精度。还具备保存为高质JPG的功能。附有四张示例图片展示生成的分形效果。
|
18天前
|
XML 开发框架 .NET
【.NET Core】常见C#代码约定
【.NET Core】常见C#代码约定
15 5
|
17天前
|
前端开发 Java C#
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
|
17天前
|
开发框架 JavaScript 前端开发
分享7个.NET开源、功能强大的快速开发框架
分享7个.NET开源、功能强大的快速开发框架
|
17天前
|
XML 开发框架 人工智能
C#/.NET/.NET Core拾遗补漏合集(24年5月更新)
C#/.NET/.NET Core拾遗补漏合集(24年5月更新)
|
17天前
|
SQL JavaScript NoSQL
.NET有哪些好用的定时任务调度框架
.NET有哪些好用的定时任务调度框架
|
18天前
|
编译器 C# C++
【.NET Core】C#预处理器指令
【.NET Core】C#预处理器指令
13 1