[英]How do I setup a mock that returns IHttpActionResult?
I'm using VisualStudio 2015, .NET 4.6, Moq 4.5.2, Nunit 3.4.1 to test a WebApi2 Controller.我正在使用 VisualStudio 2015、.NET 4.6、Moq 4.5.2、Nunit 3.4.1 来测试 WebApi2 控制器。 However, I am getting a
null
response object when mocking the intended controller method:但是,在模拟预期的控制器方法时,我得到了一个
null
响应对象:
var response = actionResult as NegotiatedContentResult;
var response = actionResult as NegotiatedContentResult;
I am guessing I must be setting up my mock of the UserService
incorrectly?我猜我一定是错误地设置了我的
UserService
模拟?
My suspicion is that this part is the culprit:我怀疑这部分是罪魁祸首:
userServiceMock.Setup(service => service.InsertOrUpdateUser( It.IsAny())).
userServiceMock.Setup(service => service.InsertOrUpdateUser(It.IsAny()))。 Returns(1);
退货(1);
As I am getting the following in the output window:当我在输出窗口中得到以下内容时:
'((System.Web.Http.Results.OkNegotiatedContentResult)actionResult).Request' threw an exception of type 'System.InvalidOperationException'
'((System.Web.Http.Results.OkNegotiatedContentResult)actionResult).Request'抛出了一个'System.InvalidOperationException'类型的异常
Is the problem that I am telling Moq to expect a return value of 1, but the Put method returns OkNegotiatedContentResult
?问题是我告诉 Moq 期望返回值为 1,但 Put 方法返回
OkNegotiatedContentResult
吗?
My questions are (possibly the same question):我的问题是(可能是同一个问题):
1) Am I setting up my Moq correctly and 1)我是否正确设置了我的起订量并且
2) how do I resolve the problem so my response object is populated? 2)如何解决问题,以便填充我的响应对象?
Thanks much.非常感谢。
Here is the Test method:下面是测试方法:
[Test]
public void Put_ShouldUpdate_User()
{
// Arrange
var userServiceMock = new Mock<IUserService>();
userServiceMock.Setup(service => service.InsertOrUpdateUser(
It.IsAny<User>())).Returns(1);
var controller = new UsersController(userServiceMock.Object);
// Act
IHttpActionResult actionResult = controller.Put(
new User()
{
Id = 1,
Name = "Joe"
});
var response = actionResult as NegotiatedContentResult<User>;
// Assert:
Assert.IsNotNull(response);
var newUser = response.Content;
Assert.AreEqual(1, newUser.Id);
Assert.AreEqual("Joe", newUser.Name);
}
Here is the UserController
method:这是
UserController
方法:
// PUT api/users/1
public IHttpActionResult Put(User user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
return Ok(_userService.InsertOrUpdateUser(user));
}
Finally, the method for the UserService:最后,UserService的方法:
public int InsertOrUpdateUser(User user)
{
return _userRepository.InsertOrUpdateUser(user);
}
According to your code IUserService
has根据您的代码
IUserService
有
public interface IUserService {
int InsertOrUpdateUser(User user);
}
which returns an int
.它返回一个
int
。
If you do the following in your controller如果您在控制器中执行以下操作
return Ok(_userService.InsertOrUpdateUser(user));
then based on the interface and your setup mock, that will return a response type of OkNegotiatedContentResult<int>
.然后基于接口和您的设置模拟,将返回
OkNegotiatedContentResult<int>
的响应类型。 But in your test you do this但是在你的测试中你这样做
var response = actionResult as NegotiatedContentResult<User>;
where you cast your returned result as NegotiatedContentResult<User>
this will cause Assert.IsNotNull(response);
您将返回的结果转换为
NegotiatedContentResult<User>
这将导致Assert.IsNotNull(response);
to fail as the cast will result in response
being null
.失败,因为转换将导致
response
为null
。
Given the asserts of your test then you would have to update your controller's Put
method to return the User user
after the mocked action like so...鉴于您的测试断言,那么您必须更新控制器的
Put
方法以在模拟操作之后返回User user
,如下所示...
public IHttpActionResult Put(User user) {
if (!ModelState.IsValid) {
return BadRequest(ModelState);
}
var count = _userService.InsertOrUpdateUser(user);
if(count == 1)
return Ok(user);
else
return BadRequest(); // 500 (Internal Server Error) you choose.
}
and also update the test as follows并更新测试如下
//...other code removed for brevity
var response = actionResult as OkNegotiatedContentResult<User>;
// Assert:
Assert.IsNotNull(response);
var newUser = response.Content;
Assert.AreEqual(1, newUser.Id);
Assert.AreEqual("Joe", newUser.Name);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.