我正在使用xUnit工具在点网核心中编写单元测试用例。在此示例中,我还尝试模拟控制器的受保护方法。
public interface ITestService {
string GetString(string testString);
}
public class TestModel {
string testValue { get; set; }
}
public class TestController : Controller
{
readonly ITestService testService;
public TestController() {
}
public TestController(ITestService _testService) {
testService = _testService;
}
[HttpPost]
public async Task<IActionResult> Post([FromBody]TestModel testModel)
{
string test = GetString("testNew");
await Task.Run(() => "test");
return Ok(test);
}
protected virtual string GetString(string testString)
{
return "test" + testString;
}
}
因此,我将需要模拟控制器本身,以在其调用方法中测试受保护的方法单元。
但是当我使用模拟对象调用控制器的方法时,我得到的是 Null 值。
public class TestControllerTest
{
private Mock<ITestService> MockTestService { get; }
TestController controller { get; }
public TestControllerTest()
{
MockTestService = new Mock<ITestService>();
controller = new TestController(MockTestService.Object);
}
[Fact]
public void Post_TakesTestString_ReturnsString()
{
var MockController = new Mock<TestController>(MockTestService.Object);
MockController.Protected().Setup<string>("GetString", ItExpr.IsAny<string>()).Returns("testMockValue").Verifiable();
var result = MockController.Object.Post(new TestModel() { }).Result;
// result returns NULL value
MockController.Protected().Verify("GetString", Times.Once(), ItExpr.IsAny<string>());
}
}
我的问题在代码的下一行-
var result = MockController.Object.Post(new TestModel() { }).Result;
我希望哪个返回Null值,行应该返回带有测试字符串的OkObjectResult
。
答案 0 :(得分:0)
由于正在模拟被测主题类,因此需要调用实际的目标方法。
启用CallBase
属性为true的情况,否则默认行为是为未设置要调用的成员返回null。
例如
public class TestControllerTest {
[Fact]
public async Task Post_TakesTestString_ReturnsString() {
//Arrange
var MockTestService = new Mock<ITestService>();
var MockController = new Mock<TestController>(MockTestService.Object) {
CallBase = true //<--
};
MockController.Protected().Setup<string>("GetString", ItExpr.IsAny<string>()).Returns("testMockValue").Verifiable();
TestController controller = MockController.Object;
//Act
var result = await controller.Post(new TestModel() { });
//Assert
MockController.Protected().Verify("GetString", Times.Once(), ItExpr.IsAny<string>());
}
}