您的位置:首页 > 其它

.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>
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));
}
  • 测试结果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: