c# - 模拟副作用

标签 c# unit-testing mocking moq

使用 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;
    }
}

我使用的是 Moq 4.0.10827.0。

最佳答案

您可以将返回设置为 Func<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 并使用它而不是模拟。

关于c# - 模拟副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10931930/

相关文章:

c# - 为视频生成缩略图

c# - 将鼠标拖到控件上以激活它们?

java - Mockito:通缉但未调用

unit-testing - 找不到模块测试路径

c - 是否可以在运行时交换 C 函数实现?

testing - 如何模拟 'new' 运算符

unit-testing - 如何用Moq模拟对具体对象的函数调用?

c# - 使用枚举标志位的 WPF 基于权限的授权

C#:如果传递对象变量,对方法参数使用 ref/out 有什么不同吗?

c# - 如何对期望通过引用更新对象的方法进行单元测试?