我正在使用Moq
来测试某些void方法的行为。使用MockBehaviour.Strict
必须在Arrange
步骤中指定对模拟的每次调用。这导致许多测试没有任何Assert
(或验证)步骤。通过条件只是测试运行而没有抛出异常。我错过了什么吗?使用严格模拟时,Arrange, Act, Assert
模式是否不合适?是否有更多语义方法来布局这些测试?
一个微不足道的例子......
[TestClass]
public void DeleteUser_ShouldCallDeleteOnRepository()
{
// Arrange
var userRepository = new Mock<IUserRepository>(MockBehavior.Strict);
int userId = 9;
userRepository.Setup(x => x.Delete(userId));
var controller = new UserController(userRepository.Object);
// Act
controller.DeleteUser(userId);
// Assert
// ...?
}
答案 0 :(得分:24)
你的模拟取代了合作者。理想情况下,它可以做以下两件事之一:
当模拟提供信息或数据时,这应该是存根就足够了。您可以将模拟的返回值设置为所需的信息。这应该是 Arrange 的一部分。
当模拟正在完成工作时,委派可以验证。这就是为什么你有 Assert 。
你在严格的互动中做的是确保每一次互动都是预期的,基本上说,“这就是我期望发生的事情,如果发生任何其他事情那就错了。”这是对Act,Arrange,Assert的另一种测试,它说:“在这种情况下,当我做这些事情时,我应该得到这个结果。”
使用“漂亮”的模拟,你只需要担心你感兴趣的交互。例如,如果我是一个控制器,我在一个存储库中查找一些信息,验证它一个验证器,然后将结果保存在另一个存储库中,我可能会进行多次测试:
使用严格模拟,你必须做所有期望,即使你感兴趣的只是“保存”。通过使用一个漂亮的模拟,我们可以分解行为的不同方面,并且只关注每个测试中的一个。
作为额外奖励,好的模拟可以让你做到:
严格的模拟让你做到:
第一个通常被认为更具可读性。