【问题标题】:Mocking side effects模拟副作用
【发布时间】:2012-06-07 12:37:03
【问题描述】:

使用 Moq,是否可以设置模拟属性以使其发生变异?

例如,给定:

public interface IService // To be mocked.
{
    bool IsConnected { get; }
}

是否可以设置一个模拟 IService 以使以下通过?

var mockService = new Mock<IService>();

// Setup mockService so IsConnected mutates...?

bool before = mockService.Object.IsConnected;

bool after = mockService.Object.IsConnected;

Assert.AreNotEqual(before, after);

当然,这个设置不能解决问题:

mockService.SetupGet(service => service.IsConnected).Returns(false);
mockService.SetupGet(service => service.IsConnected).Returns(true);

这与我对 Moq 没有实现记录/播放模型的理解一致。

这是一个更现实的例子:

public interface IService // To be mocked.
{
    bool IsConnected { get; }

    void Connect(); // Mutates IsConnected.
}

class Client // To be tested
{
    private readonly IService service;

    public Client(IService service)
    {
        this.service = service;
    }

    public bool DoWork()
    {
        if (!service.IsConnected)  // In test, IsConnected should return false.
        {
            service.Connect();
        }

        if (!service.IsConnected) // In test, IsConnected should return true.
        {
            return false;
        }

        // ... yada yada yada more code

        return true;
    }
}

我使用的是最小起订量 4.0.10827.0。

【问题讨论】:

  • 你确定你在测试正确的东西吗?根据我的经验,当你尝试做这样的事情时,你通常是在你的单元范围之外进行测试。 => 在这种情况下:ClientTest 是否需要导入来测试服务?这不应该发生在 ServiceTest 中吗?
  • @Team-JoKi 好点。理想情况下,连接状态将是 DoWork 测试的先决条件。理想情况下。

标签: c# unit-testing mocking moq


【解决方案1】:

您可以将 Returns 设置为 Func&lt;bool&gt; 而不是布尔值。然后,您将编写该 func 以更改其结果。有点像....

bool isConnected = false
var mockService = new Mock<IService>();
// Setup mockService so IsConnected mutates...?
mockService.Setup(s => s.Connect()).Callback(() => isConnected = true);
mockService.SetupGet(s => s.IsConnected).Returns(() => isConnected);

bool before = mockService.Object.IsConnected;

mockService.Object.Connect();

bool after = mockService.Object.IsConnected;

Assert.AreNotEqual(before, after);

但是,根据您的服务变得多么复杂,您可能需要考虑制作一个 FakeService 并使用它而不是模拟。

【讨论】:

  • 我实际上是从一个 FakeService 开始的,但后来决定用一个 mock 来尝试它,这让我来到了这里。谢谢。
猜你喜欢
  • 2011-10-17
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 2022-12-20
  • 1970-01-01
  • 2021-11-10
  • 2014-03-02
相关资源
最近更新 更多