【问题标题】:Unit tests to catch exception in controller method单元测试以在控制器方法中捕获异常
【发布时间】:2019-02-03 13:23:34
【问题描述】:

我正在尝试在 xUnit 中为 ASP.NET Core 项目学习单元测试。为了实现它,我创建了简单的 ASP.NET Core 项目来对其进行测试。但是,由于错误地测试了控制器方法中捕获的异常,我无法获得 100% 的测试覆盖率。

这是我正在测试的控制器方法:

        [HttpGet]
        public async Task<IEnumerable<User>> GetUsers()
        {
            try
            {
                var users = await _repository.User.GetAllUsersAsync();
                return users;
            }
            catch (Exception e)
            {
                _logger.LogError($"Error in GetUsers: {e}");
                return null;
            }
        }

这是我在 xUnit 中的单元测试方法:

        [Fact]
        public async Task GetUsers_WhenCalled_ReturnsCorrectAmountOfUsers()
        {
            //Arrange
            var mockRepo = new Mock<IRepositoryWrapper>();
            mockRepo.Setup(repo => repo.User.GetAllUsersAsync())
                .ReturnsAsync(GetTestUsers());
            var controller = new UsersController(mockRepo.Object, _logger, _service);

            //Act
            var result = await controller.GetUsers();

            //Assert
            var model = Assert.IsAssignableFrom<IEnumerable<User>>(result);
            model.Count().Should().Be(3);
            Assert.Throws<NullReferenceException>(() => 
            _controller.GetUsers().Exception);
        }

当我运行测试时,一切都变为绿色状态,但是在控制器类中,我看不到带有 catch 块范围的行旁边的“绿色勾号”。我真的很想知道如何编写正确的代码来测试 catch 块中的异常!

【问题讨论】:

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


    【解决方案1】:

    需要进行另一项测试,以在执行时引发异常。

    例如

    [Fact]
    public async Task GetUsers_WhenCalled_HandlesException() {
        //Arrange
        var mockRepo = new Mock<IRepositoryWrapper>();
        mockRepo
            .Setup(repo => repo.User.GetAllUsersAsync())
            .ThrowsAsync(new InvalidOperationException());
    
        var controller = new UsersController(mockRepo.Object, _logger, _service);
    
        //Act
        var result = await controller.GetUsers();
    
        //Assert
        Assert.IsNull(result);
        //Can also assert what logger records
    }
    

    在上面的示例中,当GetAllUsersAsync 被调用时,它会抛出一个异常,该异常将在try-catch 中被捕获,并允许代码按预期进行测试。

    【讨论】:

    • 谢谢!这确实有效。我所要做的就是为 ILogger 假添加一个 Mock 并将其传递给 UsersController 初始化。
    猜你喜欢
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多