.NET Core之单元测试(三):Mock框架Moq的使用
2020-02-23 20:27
155 查看
编写一个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,其中有三个依赖项:
SqliteDbContext,
ILogger<SampleController>和
IFooAPI实现的功能:先获取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)); }
- 测试结果
相关文章推荐
- 如何使用Nunit3在VS2017中进行.NET Core和.NET Standard项目单元测试
- 使用xUnit为.net core程序进行单元测试
- 使用xUnit为.net core程序进行单元测试(中)
- 使用xUnit为.net core程序进行单元测试(2)
- 使用xUnit为.net core程序进行单元测试(3)
- 使用xUnit为.net core程序进行单元测试(1)
- 使用xUnit为.net core程序进行单元测试(4)
- 使用xUnit为.net core程序进行单元测试(4)
- 使用xUnit为.net core程序进行单元测试(1)
- 使用xUnit为.net core程序进行单元测试(上)
- .NET Core之单元测试(四):Fluent Assertions的使用
- net core WebApi——使用xUnits来实现单元测试
- NET Core中使用Irony实现自己的查询语言语法解析器
- maven下使用 junit对 spring进行单元测试
- Net Core 使用外部登陆提供程序登陆的流程,以及身份认证的流程
- 使用 Cobertura 和反射机制提高 Java 单元测试中的代码覆盖率
- [转]在.NET环境中使用单元测试工具NUnit
- 使用VisualStudio进行单元测试之四 顺序测试
- Dojo 的单元测试框架D.O.H的使用
- 在 .NET Core 中结合 HttpClientFactory 使用 Polly(下篇)