Wat*_*tap 3 c# unit-testing moq mocking
使用 Moq,是否可以设置模拟属性以使其发生变化?
\n\n例如,给定:
\n\npublic interface IService // To be mocked.\n{\n bool IsConnected { get; }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n是否可以设置 IService 的模拟以使以下内容通过?
\n\nvar mockService = new Mock<IService>();\n\n// Setup mockService so IsConnected mutates...?\n\nbool before = mockService.Object.IsConnected;\n\nbool after = mockService.Object.IsConnected;\n\nAssert.AreNotEqual(before, after);\n
Run Code Online (Sandbox Code Playgroud)\n\n当然,这个设置并不能解决问题:
\n\nmockService.SetupGet(service => service.IsConnected).Returns(false);\nmockService.SetupGet(service => service.IsConnected).Returns(true);\n
Run Code Online (Sandbox Code Playgroud)\n\n这与我的理解是一致的,即 Moq 没有实现记录/回放模型。
\n\n这是一个更现实的例子:
\n\npublic interface IService // To be mocked.\n{\n bool IsConnected { get; }\n\n void Connect(); // Mutates IsConnected.\n}\n\nclass Client // To be tested\n{\n private readonly IService service;\n\n public Client(IService service)\n {\n this.service = service;\n }\n\n public bool DoWork()\n {\n if (!service.IsConnected) // In test, IsConnected should return false.\n {\n service.Connect();\n }\n\n if (!service.IsConnected) // In test, IsConnected should return true.\n {\n return false;\n }\n\n // ... yada yada yada more code\n\n return true;\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\nI\xe2\x80\x99m 使用起订量 4.0.10827.0。
\n您可以将 Returns 设置为 aFunc<bool>
而不是 bool。然后,您将编写该函数以更改其结果。就像是....
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);
Run Code Online (Sandbox Code Playgroud)
但是,根据您的服务的复杂程度,您可能需要考虑制作 FakeService 并使用它而不是模拟。