编写一个API

新增一个接口

public interface IFoo
{
bool Ping(string ip);
}

接口实现

public class Foo : IFoo
{
public bool Ping(string ip)
{
return new Random().Next(1, 100) % 2 == 1;
}
}

编写一个待测试的API,其中有三个依赖项:SqliteDbContextILogger<SampleController>IFoo

API实现的功能:先获取SqliteDbContext中的SampleEntity,如果其中的属性StringValue值为ping,并且结果为False,则返回404,否则返回SampleEntity

[Route("api/[controller]")]
[ApiController]
public class SampleController : ControllerBase
{
private readonly SqliteDbContext _sqliteDbContext;
private readonly ILogger<SampleController> _logger;
private readonly IFoo _foo;
public SampleController(SqliteDbContext sqliteDbContext, ILogger<SampleController> logger,IFoo foo)
{
_logger = logger;
_foo = foo;
_sqliteDbContext = sqliteDbContext;
}
[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{
var sampleData = await _sqliteDbContext.SampleEntity
.SingleOrDefaultAsync(s => s.Id == id);
if (sampleData?.StringValue == "ping")
{
var pingOk = _foo.Ping("localhost");
if (!pingOk)
return NotFound();
}
return Ok(sampleData);
}
}

测试用例

  • Mock ILogger<SampleController>
var loggerMock = new Mock<ILogger<SampleController>>();
var logger = loggerMock.Object;
  • Mock Ping(string ip)
var fooMock = new Mock<IFoo>();
fooMock.Setup(foo => foo.Ping("localhost")).Returns(true);
var foo = fooMock.Object;

关于Moq的更多操作可参见:Moq4 Quickstart

  • 修改GetSqliteDbContextAsync(),新增一个ID为2的数据记录
private async Task<SqliteDbContext> GetSqliteDbContextAsync()
{
var options = new DbContextOptionsBuilder<SqliteDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
var sqliteDbContext = new SqliteDbContext(options);
sqliteDbContext.SampleEntity.Add(new Infrastructure.Entities.SampleEntity
{
Id = 1,
BoolValue = false,
DateTimeValue = DateTime.Now,
StringValue = "sample"
}); sqliteDbContext.SampleEntity.Add(new Infrastructure.Entities.SampleEntity
{
Id = 2,
BoolValue = false,
DateTimeValue = DateTime.Now,
StringValue = "ping"
});
await sqliteDbContext.SaveChangesAsync();
return sqliteDbContext;
}
  • 测试Ping==True
[TestMethod]
public async Task Get_ReturnOK_WithPingTrue()
{
// Arrange
var dbContext = await GetSqliteDbContextAsync(); var loggerMock = new Mock<ILogger<SampleController>>();
var logger = loggerMock.Object; var fooMock = new Mock<IFoo>();
fooMock.Setup(foo => foo.Ping("localhost")).Returns(true);
var foo = fooMock.Object; var controller = new SampleController(dbContext, logger, foo); // Act
var response = await controller.Get(2);
var responseModel = ((OkObjectResult)response).Value as SampleEntity; // Assert
Assert.IsInstanceOfType(response, typeof(OkObjectResult));
Assert.IsTrue(responseModel.Id == 2);
Assert.IsFalse(responseModel.BoolValue);
Assert.IsTrue(responseModel.StringValue == "ping");
}
  • 测试Ping==False
[TestMethod]
public async Task Get_ReturnOK_WithPingFalse()
{
// Arrange
var dbContext = await GetSqliteDbContextAsync(); var loggerMock = new Mock<ILogger<SampleController>>();
var logger = loggerMock.Object; var fooMock = new Mock<IFoo>();
fooMock.Setup(foo => foo.Ping("localhost")).Returns(false);
var foo = fooMock.Object; var controller = new SampleController(dbContext, logger, foo); // Act
var response = await controller.Get(2); // Assert
Assert.IsInstanceOfType(response, typeof(NotFoundResult));
}
  • 测试结果

.NET Core之单元测试(三):Mock框架Moq的使用的更多相关文章

  1. Mock 框架 Moq 的使用

    Mock 框架 Moq 的使用 Intro Moq 是 .NET 中一个很流行的 Mock 框架,使用 Mock 框架我们可以只针对我们关注的代码进行测试,对于依赖项使用 Mock 对象配置预期的依赖 ...

  2. 教育单元测试mock框架优化之路(上)

    转载:https://sq.163yun.com/blog/article/169561874192850944 众所周知,mock对于单元测试,尤其是基于spring容器的单元测试,是非常重要的.它 ...

  3. MoQ(基于.net3.5,c#3.0的mock框架)简单介绍

    我们在做单元测试的时候,常常困扰于数据的持久化问题,很多情况下我们不希望单元测试影响到数据库中的内容,而且受数据库的影响有时我们的单元测试的速度会很慢,所以我们往往希望将持久化部分隔离开,做单元测试的 ...

  4. 教育单元测试mock框架优化之路(中)

    转载:https://sq.163yun.com/blog/article/169564470918451200 三.间接依赖的bean的mock替换 对于前面提供的@Mock,@Spy+@Injec ...

  5. 单元测试mock框架——jmockit实战

    JMockit是google code上面的一个java单元测试mock项目,她很方便地让你对单元测试中的final类,静态方法,构造方法进行mock,功能强大.项目地址在:http://jmocki ...

  6. .Net Core的简单单元测试基于Mock和自定义

    首先创建 使用mock 外部依赖一般用Mock 模拟 下载包 例如 3.1:首先先要使用MOCk来模拟测试方法需要的参数,这一步为 Arrange; 简单的模拟 var mock = new Mock ...

  7. 教育单元测试mock框架优化之路(下)

    转载:https://sq.163yun.com/blog/article/169563599967031296 四.循环依赖的解决 果然! 当我将@SpyBean应用到存在有循环依赖的Bean上时, ...

  8. Net Core WebApi单元测试

    单元测试 本篇将结合这个系列的例子的基础上演示在Asp.Net Core里如何使用XUnit结合Moq进行单元测试,同时对整个项目进行集成测试. 第一部分.XUnit 修改 Project.json  ...

  9. .NET 单元测试的利剑——模拟框架Moq(简述篇)

    .NET 单元测试的利剑--模拟框架Moq 前言 这篇文章是翻译文,因为通过自己参与的项目,越发觉得单元测试的重要性,特别是当跟业务数据打交道的时候的,Moq就如雪中送炭,所以想学习这个框架,就从这篇 ...

随机推荐

  1. php5.6.39 源码安装

    1 安装依赖库 yum install -y autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel li ...

  2. 2019-2020春江云暖你先知,CAE/EDA/高校等CloudHPC领域年均复合增长率超21%

    原创: 灵魂工作室 速石科技 我猜,我们是最早和你说春天来了的人. 一年前,我们还在小心谨慎地定义着Cloud HPC,一脸娇羞地拿Novartis 诺华制药在5年前做的案例当作标杆. 不久前,Hyp ...

  3. 一个简易的 LED 数字时钟实现方法

    这个应该是已经有很多人做过的东西,我应该只是算手痒,想写一下,所以,花了点时间折腾了这个,顺便把 Dark Mode 的处理也加上了. 首先可以很明确的一点,这个真没技术含量存在,只是需要点耐心. L ...

  4. 关于django中的get_or_create方法的坑

    最近在项目中发现了这样的一个坑,那就是我们的需求是不能添加一个相同的对象到数据库中,就通过某些字段的值组合成唯一值到数据库中去查找数据,如果没有找到对象,那就创建一条新的数据库记录,而刚好django ...

  5. Jenkins介绍与安装

    什么是Jenkins ​ Jenkins的优势和应用场景 ​ ​ Jenkins安装配置管理 安装Jenkins前的环境准备(Centos 7) 1.添加yum仓库源# wget -O /etc/yu ...

  6. 图解 Kubernetes

    容器 在了解 Kubernetes 之前,让我们先了解一个容器. 因为如果不了解容器就没法聊容器编排. 容器就是...一个你塞入所有材料的容器. "材料"是指你的应用代码.依赖库, ...

  7. 异数OS TCP协议栈测试(一)--数据传输篇

    异数OS TCP协议栈测试(一)--数据传输篇 本文来自异数OS社区 github:   异数OS-织梦师(消息中间件)群: 476260389 测试目标 数据传输IO性能测试,主要是建立连接后测试收 ...

  8. [题解]CSP2019 Solution - Part B

    \(\text{orz}\) 一波现场 \(\text{A}\) 掉 \(\text{D1T3}\) 的神仙 D2T3 centroid Solution 考虑每个点 \(u\) 作为重心的贡献 假设 ...

  9. 基于javaSwing的贪食蛇游戏

    这个项目时,是我好几年前写的了.但对刚入门,或者想瞧瞧java的图形的界面swing的同学,还是有点用处的. 在这推荐给你. 涉及技术点 swing,多线程,文件读写,多媒体文件播放等 游戏简介 该游 ...

  10. Creating Custom Helper Methods 创建自定义辅助器方法----辅助器方法 ------ 精通ASP.NET MVC 5

    创建内联的辅助器方法 和 拓展方法 好像类似的功能. 不过写在前台更直观