使用 Mocks 验证依赖项调用时的 TDD Arrange Act Assert 模式

发布于 2024-12-22 15:41:01 字数 666 浏览 3 评论 0原文

我正在使用 Moq 来测试某些 void 方法的行为。使用 MockBehaviour.Strict 对模拟的每次调用都必须在 Arrange 步骤中指定。这导致许多测试没有任何断言(或验证)步骤。通过的条件很简单,就是测试运行时没有抛出异常。我错过了什么吗?使用严格模拟时,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
    // ...?
}

I'm using Moq to test behaviour of some void methods. Using MockBehaviour.Strict every call to the mock must be specified during Arrange step. This is resulting in a lot of tests not having any Assert (or Verify) step. The pass condition is simply that the test ran without throwing an exception. Am I missing something? Is the Arrange, Act, Assert pattern unsuitable when using strict mocks? Is there a more semantic way to layout these tests?

A trivial made up example...

[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
    // ...?
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野稚 2024-12-29 15:41:01

你的模拟正在取代合作者。理想情况下,它会执行以下两件事之一:

  • 提供信息或数据
  • 完成工作

当模拟提供信息或数据时,它应该是一个存根就足够了。您可以将mock的返回值设置为所需的信息。这应该是安排的一部分。

当模拟正在执行工作时,可以验证委托。。这就是为什么你有断言

你在严格交互中所做的就是确保每一次交互都是预期的,基本上是说,“这就是我期望发生的事情,如果发生其他任何事情,那就是错误的。”这是与“行动”、“安排”、“断言”不同的测试,“在这种情况下,当我做这些事情时,我应该得到这个结果”。

通过“良好”的模拟,您只需要担心您感兴趣的交互。因此,例如,如果我是一名控制器,并且我正在一个存储库中查找一些信息,并使用验证器对其进行验证,然后将结果保存在另一个存储库中,我可能需要进行多项测试:

  • 一项检查我是否正在根据正确的信息进行验证,
  • 一项检查我如何响应错误的验证
  • ,一项检查我是否保存了该项目。

通过严格的模拟,您必须满足所有期望,即使您感兴趣的只是“保存”。通过使用一个很好的模拟,我们可以分解行为的不同方面,并在每个测试中只关注其中一个方面。

作为额外的好处,好的模拟允许你做:

  • 给定一个上下文
  • 当这个事件发生时
  • 那么这个结果应该发生

而严格的模拟让你做:

  • 给定一个上下文
  • 期望一些事情发生
  • 当我执行一个事件
  • 然后返回并阅读什么结果本来应该是这样的。

第一个通常被认为更具可读性。

Your mock is taking the place of a collaborator. It's ideally doing one of two things:

  • Providing information or data
  • Doing a job

When the mock is providing information or data, it's enough that this should be a stub. You can set up the return value of the mock to the information required. This should be part of Arrange.

When the mock is doing a job, the delegation can be verified. This is why you have Assert.

What you're doing with the strict interaction is ensuring that every single interaction is expected, basically saying, "Here's what I expect to happen, and if anything else happens it's wrong." This is a different kind of testing to Act, Arrange, Assert, which says, "In this context, when I do this stuff, then I should get this outcome."

With a "nice" mock, you only need to worry about the interactions you're interested in. So, for instance, if I'm a controller and I'm looking up some information in one repository, validating it with a validator, then saving the result in another repository, I might have several tests:

  • one to check that I'm validating against the right information
  • one to check how I'm responding to incorrect validation
  • and one to check that I save the item.

With the strict mock, you have to do all the expectations, even if all you're interested in is the "save". By using a nice mock, we can split up the different aspects of behavior and only focus on one of them in each test.

As an additional bonus, nice mocks allow you to do:

  • Given a context
  • When this event happens
  • Then this outcome should occur

Whereas strict mocks make you do:

  • Given a context
  • Expect some stuff to happen
  • When I perform an event
  • Then go back and read what the outcome should have actually been.

The first of these is generally considered more readable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文