简体   繁体   English

如何设置返回 IHttpActionResult 的模拟?

[英]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 .失败,因为转换将导致responsenull

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.

相关问题 如何在返回IHttpActionResult时对web api动作方法进行单元测试? - How do I unit test web api action method when it returns IHttpActionResult? 如何设置基于参数值动态返回结果的模拟? - How do I setup a mock that dynamically returns results based on a parameter's value? 如何返回带有错误消息或异常的 NotFound() IHttpActionResult? - How do I return NotFound() IHttpActionResult with an error message or exception? 如何实现IHttpActionResult,以便它尊重Accept标头? - How do I implement IHttpActionResult so that it respects the Accept header? 我如何嘲笑这个? - How do I mock this? mock.Setup(...).Returns(..); 不是 mocking - mock.Setup(…).Returns(..); Not mocking 如何测试返回Task的控制器方法 <IHttpActionResult> 匿名类型 - How to Test controller method which returns Task<IHttpActionResult> with anonymous type Autofac mock - 如何设置/伪造依赖项中特定方法的数据? - Autofac mock - How do I setup/fake data from specific methods in dependencies? 如何为存储库方法设置 MVC mock.Setup 和.Returns,它具有输出参数和返回类型 - How to setup MVC mock.Setup and.Returns for a repository method, which has on out parameter and a return type 我如何模拟 AddAsync? - How do I mock AddAsync?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM