模拟控制器对象方法 returns 结果中的空值
Mocked controller object method returns Null value in Result
我正在使用 xUnit 工具在 Dot net core 中编写单元测试用例。在此示例中,我还尝试模拟控制器的受保护方法。
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;
哪个 returns 空值,我预计,行应该 return OkObjectResult
带有测试字符串。
由于被测对象class也在mock中,需要调用实际的目标方法
启用 CallBase
属性 设置为 true 否则默认行为是 return 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>());
}
}
我正在使用 xUnit 工具在 Dot net core 中编写单元测试用例。在此示例中,我还尝试模拟控制器的受保护方法。
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;
哪个 returns 空值,我预计,行应该 return OkObjectResult
带有测试字符串。
由于被测对象class也在mock中,需要调用实际的目标方法
启用 CallBase
属性 设置为 true 否则默认行为是 return 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>());
}
}