我知道这个问题有点像很多问题的重复,但我一辈子都搞不清楚我是不是在犯傻,错过了一些非常明显的东西。我现在需要比我更聪明的人给我指路(或者告诉我我没有疯)。
基本上,我在一次面试中遇到了一个编码挑战(我不是想作弊,请原谅我)。现在提供的代码“工作”了,就像它构建和运行一样,除了它实际上并不工作。这里只是提供的控制器之一的一个片段(为更通用的东西更改名称)。
public class ExampleController : BaseApiController
{
private readonly SomeRepository _repository;
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> GetAll()
{
var items = await _repository.Items.GetAllAsync();
return Ok(items);
}
这是BaseApiController的外观:
[Route("api/[controller]")]
public class BaseApiController : ControllerBase
{ }
现在问题很明显了,_repository从来没有初始化过。所以我添加了一个构造函数来初始化它,并添加了DbContext(SomeRepository依赖于它):
public class ExampleController : BaseApiController
{
private readonly SomeRepository _repository;
public class ExampleController(SomeDbContext context){
_repository = new SomeRepository(context);
}
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> GetAll()
{
var items = await _repository.Items.GetAllAsync();
return Ok(items);
}
这是可行的,我通过postman测试了它,并且能够取回数据。然而,它破坏了挑战中提供的每一个单元测试。为什么?提供的测试使用基构造函数初始化ExampleController类。下面是一个示例:
public class ExampleControllerTests
{
private readonly Mock<ISomeRepository> _repository;
public ExampleControllerTests()
{
this._repository = new Mock<ISomeRepository>();
}
[Fact]
public async Task Get_OnSuccess_ReturnsListOfItems()
{
Item[] monsters = ItemFixture.GetItemsMock().ToArray();
this._repository
.Setup(x => x.Items.GetAllAsync())
.ReturnsAsync(items);
ExampleController sut = new ExampleController();
ActionResult result = await sut.GetAll();
OkObjectResult objectResults = (OkObjectResult) result;
objectResults?.Value.Should().BeOfType<Item[]>();
}
显然,我不应该修改他们提供的测试,那么有没有一种方法可以在ExampleController中获取DbContext,而无需创建一个将其作为参数的构造函数?或者,我应该自己解决测试问题(在这种情况下,如何解决?尝试初始化DbContext不起作用,因为它需要DbContextOptions)。
1条答案
按热度按时间x4shl7ld1#
看起来他们已经注册了所有需要注入控制器的依赖项,否则注入
DbContext
将会失败。你提供的测试肯定是不完整的,应该被修复。他们在模仿
ISomeRepository
,但没有以任何方式使用它。更不用说ExampleController sut = new ExampleController();
不会起作用,因为你添加了DbContext
作为构造函数参数。我假设
ISomeRepository
被绑定在DI容器的某个地方(和DbContext
一起),那么ExampleController
看起来就像这样:然后,测试将使用模拟接口来验证
GetAll
方法。