3

使用 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。

4

1 回答 1

5

您可以将 Returns 设置为 aFunc<bool>而不是 bool。然后,您将编写该 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 并使用它而不是模拟。

于 2012-06-07T12:42:28.003 回答