如何设置 returns IHttpActionResult 的模拟?
How do I setup a mock that returns IHttpActionResult?
我正在使用 VisualStudio 2015、.NET 4.6、Moq 4.5.2、Nunit 3.4.1 来测试 WebApi2 控制器。但是,在模拟预期的控制器方法时,我得到了一个 null
响应对象:
var response = actionResult as NegotiatedContentResult;
我猜我一定是错误地设置了 UserService
的模拟?
我怀疑这部分是罪魁祸首:
userServiceMock.Setup(service => service.InsertOrUpdateUser(
It.IsAny())).Returns(1);
因为我在输出中得到以下内容 window:
'((System.Web.Http.Results.OkNegotiatedContentResult)actionResult).Request'
threw an exception of type 'System.InvalidOperationException'
问题是我告诉 Moq 期望 return 值为 1,但是 Put 方法 returns OkNegotiatedContentResult
?
我的问题是(可能是同一个问题):
1) 我是否正确设置了最小起订量并且
2) 如何解决问题以便填充我的响应对象?
非常感谢。
测试方法如下:
[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);
}
这里是 UserController
方法:
// PUT api/users/1
public IHttpActionResult Put(User user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
return Ok(_userService.InsertOrUpdateUser(user));
}
最后,UserService 的方法:
public int InsertOrUpdateUser(User user)
{
return _userRepository.InsertOrUpdateUser(user);
}
根据你的代码IUserService
有
public interface IUserService {
int InsertOrUpdateUser(User user);
}
其中 return 是 int
。
如果您在控制器中执行以下操作
return Ok(_userService.InsertOrUpdateUser(user));
然后根据界面和您的设置模拟,return 响应类型为 OkNegotiatedContentResult<int>
。但是在你的测试中你这样做
var response = actionResult as NegotiatedContentResult<User>;
将 returned 结果转换为 NegotiatedContentResult<User>
这将导致 Assert.IsNotNull(response);
失败,因为转换将导致 response
成为 null
。
鉴于您的测试断言,那么您必须将控制器的 Put
方法更新为 return 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.
}
同时将测试更新如下
//...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);
我正在使用 VisualStudio 2015、.NET 4.6、Moq 4.5.2、Nunit 3.4.1 来测试 WebApi2 控制器。但是,在模拟预期的控制器方法时,我得到了一个 null
响应对象:
var response = actionResult as NegotiatedContentResult;
我猜我一定是错误地设置了 UserService
的模拟?
我怀疑这部分是罪魁祸首:
userServiceMock.Setup(service => service.InsertOrUpdateUser( It.IsAny())).Returns(1);
因为我在输出中得到以下内容 window:
'((System.Web.Http.Results.OkNegotiatedContentResult)actionResult).Request' threw an exception of type 'System.InvalidOperationException'
问题是我告诉 Moq 期望 return 值为 1,但是 Put 方法 returns OkNegotiatedContentResult
?
我的问题是(可能是同一个问题):
1) 我是否正确设置了最小起订量并且
2) 如何解决问题以便填充我的响应对象?
非常感谢。
测试方法如下:
[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);
}
这里是 UserController
方法:
// PUT api/users/1
public IHttpActionResult Put(User user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
return Ok(_userService.InsertOrUpdateUser(user));
}
最后,UserService 的方法:
public int InsertOrUpdateUser(User user)
{
return _userRepository.InsertOrUpdateUser(user);
}
根据你的代码IUserService
有
public interface IUserService {
int InsertOrUpdateUser(User user);
}
其中 return 是 int
。
如果您在控制器中执行以下操作
return Ok(_userService.InsertOrUpdateUser(user));
然后根据界面和您的设置模拟,return 响应类型为 OkNegotiatedContentResult<int>
。但是在你的测试中你这样做
var response = actionResult as NegotiatedContentResult<User>;
将 returned 结果转换为 NegotiatedContentResult<User>
这将导致 Assert.IsNotNull(response);
失败,因为转换将导致 response
成为 null
。
鉴于您的测试断言,那么您必须将控制器的 Put
方法更新为 return 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.
}
同时将测试更新如下
//...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);