通过内存方法到达 Catch 块

问题描述 投票:0回答:1

我有一个 TestController 类,我正在其中对 Controller 类执行单元测试。

Controller 类创建一个名为

_service
的 Service 类的实例。 Controller 类有一个方法,其实现如下:

    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async Task<IActionResult> Get(CancellationToken ct)
    {
        try
        {
            return Ok(await _service.GetAll(ct));
        }
        catch (Exception e)
        {
            _logger.LogError(e.Message);
            return StatusCode(StatusCodes.Status500InternalServerError, "There was an error processing your request.");
        }
    }

在我的 TestController 类中,我创建了一个名为

_mockService
的 Service 类的 Moq'ed 实例。 TestController 类中的方法之一使用
_mockService
并将其设置为引发异常,以便我可以在 Controller 类的 catch 块中测试 return 语句:

    [Fact]
    public async void Get_ReturnsIActionResult_InternalServerError()
    {
        // Setup mock
        CancellationToken ct = default(CancellationToken);
        _mockService.Setup(ms => ms.GetAll(ct)).Throws(new TaskCanceledException());

        // Test class
        var result = await _controller.Get(ct);

        // Assert results
        var objectResult = Assert.IsType<ObjectResult>(result);
        Assert.Equal(500, objectResult.StatusCode);
    }

同样,我有一个 TestRepository 类,我在 Repository 类上执行单元测试。

Repository 类创建名为

_dbContext
的 DbContext 类的实例。 Repository 类有一个方法,其实现如下:

    public async Task<IEnumerable<SomeDbSetProperty>> GetAll(CancellationToken ct = default)
    {
        try
        {
            return await _dbContext.SomeDbSetProperty.Where(p => p.IsActivated == true).ToListAsync(ct);
        }
        catch (Exception e)
        {
            _logger.LogError($"Error in GetAll: {e}");
            throw;
        }
    }

我的团队选择使用本文中概述的内存中方法,而不是 Moq'ing DbContext 类(这与我们在 TestController 类中 Moq'ed Service 类的方法类似)。 (我意识到这是一种令人沮丧的做法,但决定不是由我决定的。)

我的目标是在 TestRepository 类中创建一个测试方法,用于测试 Repository 类的 catch 块中的代码(类似于我的 TestController 类中测试 Controller 类中的 catch 块的方法)。

我的问题是我不知道如何使用内存方法来做到这一点。通过使用 Setup 和 Throws 方法可以很容易地完成 Moq,但我不知道如何使用内存方法复制该概念。也许我正在经历为什么他们不推荐内存中方法,或者也许我忽略了一些东西。

如有任何帮助,我们将不胜感激。

.net entity-framework-core xunit in-memory-database
1个回答
0
投票

在我看来,你有几个选择:

  • 与您的团队讨论并使用内存进行测试,但需要受控数据库故障模拟的测试除外。如果代码无论如何都会抛出,为什么还需要内存呢?避免复杂的模拟你不会得到任何好处。
  • 在测试期间将
  • 自定义拦截器添加到DbContext以模拟此行为。这会有点难看,但是您可以通过它们使特定的数据库命令失败。您可以模拟部分模拟。
  • 最后,不要在存储库方法中执行此逻辑。如果一开始就没有错误处理,则不需要这些测试。您可以将此逻辑放在不需要内存数据库的其他地方,并减少围绕存储库方法的重复样板文件。这里有无数的选项,从抽象基础存储库类到控制器过滤器。您可以避免对每个存储库方法进行重复的异常测试。
© www.soinside.com 2019 - 2024. All rights reserved.