【发布时间】:2014-06-07 15:27:20
【问题描述】:
我的服务层有以下方法
public ModuleResponse GetModules(ModuleRequest request)
{
var response = new ModuleResponse(request.RequestId);
try
{
response.Modules = Mapper.ToDataTransferObjects(ModuleDao.GetModules());
return response;
}
catch (Exception ex)
{
Log.Error(ex);
response.Acknowledge = AcknowledgeType.Failure;
response.Message = "An error occured.";
return response;
}
}
我有一个用 xUnit 编写的单元测试,如下所示:
[Fact]
public void GetModulesTest()
{
//Arrange
var mockModuleDao = Mock.Create<IModuleDao>();
var mockLog = Mock.Create<ILog>();
var mockAuditDao = Mock.Create<IAuditDao>();
var moduleList = new List<ModuleItem>
{
new ModuleItem {Id = 100, Category = "User Accounts", Feature = "Users"},
new ModuleItem {Id = 101, Category = "User Accounts", Feature = "Roles Permissions"}
};
mockModuleDao.Arrange(dao => dao.GetModules()).Returns(moduleList);
IUserManagementService userService = new UserManagementService(mockModuleDao, mockLog, mockAuditDao);
var request = new ModuleRequest().Prepare();
//Act
var actualResponse = userService.GetModules(request);
//Assert
Assert.Equal(AcknowledgeType.Success, actualResponse.Acknowledge);
Assert.Equal(2, actualResponse.Modules.Count);
}
现在我的代码中有一大堆检索方法,类似于上面的方法。
测试这些方法是多余的吗?我的意思是,它们几乎可以肯定通过测试,除非我搞砸了我的映射逻辑或其他东西。
另外,在测试检索方法时,我应该测试什么?在我上面的场景中,我有 2 个断言语句,1 个用于检查响应是否成功,第 2 个是检查列表的计数。
这就足够了吗?或者如何进一步改进以提高这种单元测试的价值?
【问题讨论】:
-
你是正确的。您的测试实际上并没有测试您认为它正在测试的内容 - 您实际上是在测试您的映射。将您的测试范围限制为映射,并且测试具有价值。
-
所以一般来说,除非我的检索方法包含某种行为逻辑,否则它们是多余的?
-
根据我的经验.. 是的。除非您在服务和映射器之间执行一些集成测试——即检查某些方法是否被服务方法调用——否则它是多余的。现在,如果您的服务方法实际上有其他逻辑,那么当然,测试它们.. 但我在这里看到的只是对映射的测试。纯 TDD 无论如何都会声明测试它(我认为).. 但我个人不会。
-
TDD 纯粹主义者检查。:-) 正如@SimonWhitehead 所猜测的,我认为您应该进行这些测试,但原因如下:它们引起了您的注意冗余代码/功能(我敢打赌,不只是 测试 是冗余的)。我们可以把它写成必要的邪恶——在某些情况下确实如此——或者我们可以重新检查我们的设计并考虑可以重构它的方式。
-
还有未来变化的说法。如果您编写了一个测试,将来对此方法的更改将被覆盖。而如果您没有编写一个,则可以进行更改并且您的测试覆盖率会降低。这实际上是足以让我改变看法的理由。我在此收回我之前所说的一切:)
标签: c# .net unit-testing mocking xunit.net