模拟控制器对象方法在结果中返回 Null 值



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

因此,我需要模拟控制器本身,以便在其调用方法中测试受保护的方法单元。

但是当我使用 Mocked 对象调用控制器的方法时,我得到了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;

它返回空值,我希望,行应该返回带有测试字符串的OkObjectResult

由于被测试的主题类也被模拟,因此需要调用实际的目标方法。

启用此选项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>());
}
}

最新更新