自动Mock,让编写单元测试更简单
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自动Mock,让编写单元测试更简单相关的知识,希望对你有一定的参考价值。
问题
由于依赖注入,特别是构造函数注入的广泛使用,使得编写单元测试时,需要使用Mock框架(例如Moq
)生成测试类的依赖接口的"模拟"实现,并验证接口是否按预期使用。
例如eShopOnContainers中的测试代码就使用了Moq
,实现如下:
private readonly Mock<IMediator> _mediatorMock;
private readonly Mock<IOrderQueries> _orderQueriesMock;
private readonly Mock<IIdentityService> _identityServiceMock;
private readonly Mock<ILogger<OrdersController>> _loggerMock;
public OrdersWebApiTest()
{
_mediatorMock = new Mock<IMediator>();
_orderQueriesMock = new Mock<IOrderQueries>();
_identityServiceMock = new Mock<IIdentityService>();
_loggerMock = new Mock<ILogger<OrdersController>>();
}
[Fact]
public async Task Cancel_order_with_requestId_success()
{
//Arrange
_mediatorMock.Setup(x => x.Send(It.IsAny<IdentifiedCommand<CancelOrderCommand, bool>>(), default(CancellationToken)))
.Returns(Task.FromResult(true));
//Act
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object, _loggerMock.Object);
var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
//Assert
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
}
可以看到OrdersController
依赖了4个接口,而每个测试用例都必须将Mock对象传入构造函数,一旦更改了OrdersController
的构造函数参数,那么你将需要更改大量单元测试代码。
如何简化这部分工作?
Moq.AutoMocker
Moq.AutoMocker是一款基于Moq的IoC容器,它可以用来自动创建待测试类的依赖。
引用nuget包Moq.AutoMock
之后,上面的测试代码可以修改如下:
[Fact]
public async Task Cancel_order_with_requestId_success()
{
//Arrange
var autoMocker = new AutoMocker();
var orderController = autoMocker.CreateInstance<OrdersController>();
var mediatorMock = autoMocker.GetMock<IMediator>();
mediatorMock.Setup(x => x.Send(It.IsAny<IdentifiedCommand<CancelOrderCommand, bool>>(), default(CancellationToken)))
.Returns(Task.FromResult(true));
//Act
var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
//Assert
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
}
可以看到,无需提前生成Mock对象,autoMocker.CreateInstance<T>
即可创建指定类型的实例。autoMocker.GetMock<T>
可以获得依赖接口的Mock实例,然后像以前一样,执行Setup
或Verify
方法。
结论
Moq.AutoMocker大大减少了在单位测试中编写重复Mock代码的数量,简化了待测试类的生成。
如果你使用Moq,我强烈推荐它。
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!
以上是关于自动Mock,让编写单元测试更简单的主要内容,如果未能解决你的问题,请参考以下文章