当测试用例参数正在更改具有默认值的参数时,单元测试用例的问题

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

我对编程非常陌生,只了解基础知识。

我目前正在为.net core 2.2控制器编写单元测试。我正在使用Rider,Nunit和Moq。

这里是我遇到问题的单元测试之一:

    [Test]
    [TestCase(true)]
    [TestCase(false)]
    public async Task GetPersonAsync_PersonDoesExist_ReturnOk(bool includeRelated)
    {
        _repository.Setup(r => r.GetPersonAsync(_id, includeRelated)).ReturnsAsync(_person);

        _mapper.Setup(m => m.Map<Person, GetPersonResource>(It.IsAny<Person>())).Returns(_getPersonResource);

        var result = await _controller.GetPersonAsync(_id);

        Assert.That(result, Is.TypeOf<OkObjectResult>());
    }

这是我的构造器/顶部和该单元测试的设置:

public class PersonsControllerTests
{
    private Mock<IMapper> _mapper;
    private Mock<IUnitOfWork> _unitOfWork;
    private Mock<IClientsRepository> _repository;
    private PersonsController _controller;
    private int _id;
    private Person _person;
    private GetPersonResource _getPersonResource;
    private CreatePersonResource _createPersonResource;
    private UpdatePersonResource _updatePersonResource;

    [SetUp]
    public void Setup()
    {
        _mapper = new Mock<IMapper>();
        _unitOfWork = new Mock<IUnitOfWork>();
        _repository = new Mock<IClientsRepository>();

        _controller = new PersonsController(_mapper.Object, _repository.Object, _unitOfWork.Object);

        _id = 1;
        _person = new Person {Id = 1};
        _getPersonResource = new GetPersonResource {Id = 1};
        _createPersonResource = new CreatePersonResource {Code = "a"};
        _updatePersonResource = new UpdatePersonResource {Code = "a"};
    }

这是我的控制器中的GetPersonAsync方法:

    [HttpGet("{id}")]
    public async Task<IActionResult> GetPersonAsync(int id)
    {
        var person = await repository.GetPersonAsync(id);

        if (person == null)
            return NotFound();

        return Ok(mapper.Map<Person, GetPersonResource>(person));
    }

这是我的控制器的构造器/顶部:

[Route("/api/persons")]
public class PersonsController : Controller
{
    public IMapper mapper { get; }
    private readonly IClientsRepository repository;
    private readonly IUnitOfWork unitOfWork;

    public PersonsController(IMapper mapper, IClientsRepository repository, IUnitOfWork unitOfWork)
    {
        this.unitOfWork = unitOfWork;
        this.repository = repository;
        this.mapper = mapper;
    }

这是我的存储库中的GetPersonAsync方法:

    public async Task<Person> GetPersonAsync(int id, bool includeRelated = true) 
    {
        if (!includeRelated)
            return await context.Persons
                .FirstOrDefaultAsync(p => p.Id == id);
        else
            return await context.Persons
                .Include(p => p.Clients)
                .Include(p => p.ClientRelateds)
                    .ThenInclude(cr => cr.ClientRelationType)
                .FirstOrDefaultAsync(p => p.Id == id);
    }

这是我的IRepository中的GetPersonAsync签名:

Task<Person> GetPersonAsync(int id, bool includeRelated = true);

我遇到的问题是,每当我运行测试并将includeRelated参数更改为false时(默认情况下为true,我的测试都会失败。

例如,在我上面给出的测试用例为false的测试中,它应该返回Ok,但返回NotFound,当我使用真实的测试用例时,它返回Ok并通过,这正是我想要的。当我想查看是否保存模型时,我也得到相同的结果。我的将includeRelated设置为true的测试会调用_unitOfWork.CompleteAsync方法,但是当includeRelated设置为false时不会调用它。

当我在存储库中设置包括与false有关的include的默认值时,我所有包含includeRelated true的测试用例都会失败,而includeRelated false传递会失败。

[我很有可能在项目或单元测试中犯了一个错误,但是在我看来,如果我错了,请纠正我,当我在模拟存储库时,Moq会出现错误。存储库的实际实现(即,includeRelated的默认值为true)一点都不重要。

c# .net-core nunit moq rider
1个回答
0
投票

请注意,此处的存储库代码无关紧要,因为您在嘲笑它-该代码永远不会执行。相反,将为您设置的调用返回结果-所有其他调用都为返回类型返回.NET默认值-通常情况下为null

在您的设置中,已使存储库模拟条件为,当使用参数(1, true)(1, false)调用时,返回值only,具体取决于正在运行的测试用例。每当仅使用参数(1)调用它时,它将返回null。 IOW,您必须设置将实际使用的呼叫。您may希望设置所有三种可能性,以防灯具中的某些测试使用默认设置。

顺便说一句,使用默认参数测试方法非常棘手。

次要nitpick:您不需要[Test]和IMO,在这种情况下它是丑陋且令人困惑的-乍一看就像是三个测试案例而不是两个测试案例。

© www.soinside.com 2019 - 2024. All rights reserved.