使用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。
答案 0 :(得分:3)
您可以将返回值设置为Func<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并使用它而不是模拟。