我使用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()))的返回(1);
我在输出窗口中收到以下内容:
'((System.Web.Http.Results.OkNegotiatedContentResult)的ActionResult).Request' 抛出类型' System.InvalidOperationException'
的例外
问题是我告诉Moq期望返回值为1,但Put方法返回OkNegotiatedContentResult
?
我的问题是(可能是同一个问题):
1)我是否正确设置了Moq并
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);
}
答案 0 :(得分:1)
根据您的代码private static Random r = new Random();
public static int[] makeSet(int n, int max) {
// The next line guarantees the result is divisible by n
int currentMax = n * (1 + r.nextInt(max / n));
Set<Integer> s = new HashSet<Integer>();
// Generate a set of unique values between 0 and the currentMax,
// containing those bounds
s.add(0);
s.add(currentMax);
do {
s.add(r.nextInt(currentMax));
} while(s.size() <= n);
Integer[] values = new Integer[n + 1];
/*
* Convert to array, sort the results, and find successive
* differences. By construction, those differences WILL sum
* to the currentMax, which IS divisible by the number of
* values generated by differencing!
*/
s.toArray(values);
Arrays.sort(values);
int[] results = new int[n];
for(int i = 0; i < n; ++i) {
results[i] = values[i+1] - values[i];
}
return results;
}
已
IUserService
返回public interface IUserService {
int InsertOrUpdateUser(User user);
}
。
如果您在控制器中执行以下操作
int
然后根据界面和您的设置模拟,返回响应类型return Ok(_userService.InsertOrUpdateUser(user));
。但是在你的测试中你做到了这个
OkNegotiatedContentResult<int>
您将返回的结果转换为var response = actionResult as NegotiatedContentResult<User>;
,这会导致NegotiatedContentResult<User>
失败,因为广告素材会导致Assert.IsNotNull(response);
为response
。
鉴于测试的断言,您必须更新控制器的null
方法,以便在模拟操作之后返回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.
}