WebApi操作方法返回null

时间:2019-09-10 13:16:27

标签: c# unit-testing asp.net-core asp.net-core-webapi

整整一天,我找不到解决方案。 从PostMan调用时,我的控制器的ActionMethod运行正常。 但是,当我从单元测试方法中调用它时,它始终返回null。

这是我的代码。 我已经在StackOverflow上找到了答案: construct
但这不能解决我的问题。

这是我的ActionMethod

[HttpPost("register")]
        public async Task<IActionResult> RegisterUser([FromBody] CreateUserRequest request)
        {
            if (!ModelState.IsValid)
                return BadRequest(ModelState);
            try
            {
                //  Map request with dto and give to service
                CreateUserRequestDto createDto = _mapper.Map<CreateUserRequestDto>(request);
                CreateUserResponseDto response = await _userService.CreateUser(createDto);

                if (response.IsSuccess)
                {
                    Success success = new Success(message: SuccessMessages.UserCreated, data: response);
                    return Ok(success);
                }

                Error error = new Error(message: ErrorMessages.UserRegistrationFailed, description: response.Error.Description);
                return BadRequest(error);
            }
            catch (Exception ex)
            {
                return HandleException(ex);
            }
        }

这是我的考试班

    public class MockAccountControllerTests
    {
        readonly UserController _accountController;

        public MockAccountControllerTests()
        {
            Mock<IMapper> _mockMapper = new Mock<IMapper>();
            Mockers.InitializeMappers(_mockMapper);
            UserManager<AppUser> _mockUserManager = Mockers.MockUserManager<AppUser>().Object;
            UserRepository _mockUserRepository = new Mock<UserRepository>(_mockUserManager, _mockMapper.Object).Object;
            UserService _mockUserService = new Mock<UserService>(_mockUserRepository).Object;

            _accountController = new Mock<UserController>(_mockUserService, _mockMapper.Object).Object;
        }

        [Fact]
        public async Task RegisterUser_NullUserNamePassword_ThrowsException()
        {
            CreateUserRequest request = RequestHelpers.CreateUserRequest(null, null);

            IActionResult result = await _accountController.RegisterUser(request);

            ObjectResult badRequest = result as ObjectResult;

            Assert.NotNull(badRequest);
            Assert.True(badRequest is BadRequestObjectResult);
            Assert.Equal(StatusCodes.Status400BadRequest, badRequest.StatusCode);
            Assert.NotNull(badRequest.Value);
            Assert.IsType<Error>(badRequest.Value);
        }
    }

在我的测试方法的这一行

var result = await _accountController.RegisterUser(request);

resultnull

我还尝试将BadRequest的值分配给这样的变量

var a = BadRequest("Test Message"); 在这种情况下,a也是null

该如何纠正? 我在ActionMethod或TestMethod中做错什么了吗? 请检查。

2 个答案:

答案 0 :(得分:3)

这是罪魁祸首:

 _accountController = new Mock<UserController>(_mockUserService, _mockMapper.Object).Object;

不要模拟您的被测系统,因为那样您就不测试代码,而只是测试Moq是否执行了应做的工作。而且确实如此:它为不是null的方法调用返回默认值(对于引用类型为SetUp()。)

因此,将其初始化为控制器的实际实例:

 _accountController = new UserController(_mockUserService, _mockMapper.Object);

另请参阅:docs.microsoft.com上的Test controller logic in ASP.NET Core

答案 1 :(得分:-1)

唯一可能的解释是,无论result的类型是什么,都不是从ObjectResult派生的,因此通过ObjectResult将其强制转换为as会导致生成空值返回。

问题是,除了在您返回ObjectResult的catch块中,我看不到任何输出返回的不是HandleException(ex)派生的东西。目前尚不清楚什么返回的类型在这里,所以我只能假设这就是您的问题所在。简而言之,需要返回一个ObjectResult类型。诸如BadRequestResult之类的名称中没有Object的事物源自StatusCodeResult,与ObjectResult没有血统。

还值得一提的是,一旦您超过了这个主张,您的下一个就会失败。由于您要将结果强制转换为ObjectResult并将其保存到badRequest,因此断言Assert.True(badRequest is BadRequestObjectResult)总是会失败,因为它始终是ObjectResult,而不是{{ 1}}。