Я довольно новичок в программировании и знаю только основы.
В настоящее время я пишу юнит-тест для контроллера .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);
}
Вот моя подпись GetPersonAsync в моем IRepository:
Task<Person> GetPersonAsync(int id, bool includeRelated = true);
Проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда я запускаю тест иизмените аргумент includeRelated на false, что по умолчанию равно true, мои тесты не пройдены.
Например, в тесте, который я дал выше, мой тест с тестом case false, должен возвращать Ok, но возвращает NotFound,когда я использую настоящий тестовый пример, он возвращает Ok и проходит, что я и хочу. Я также получаю то же самое, когда хочу посмотреть, сохранена ли модель. Мой тест, где includeRelated установлен в true, вызывает мой метод _unitOfWork.CompleteAsync, но не вызывает его, когда для includeRelated установлено значение false.
Когда я устанавливаю значение по умолчанию include, связанное с false, в моем репозитории во всех моих тестовых случаяхс includeRelated true с ошибками и includeRelated false pass.
Существует большая вероятность, что я либо допустил ошибку в своем проекте или в моем модульном тесте, но мне кажется, что это так, и исправьте меня, если я ошибаюсь,В Moq есть ошибка, так как я проверяю хранилище, и фактическая реализация хранилища (т. е. значение по умолчанию true для includeRelated) вообще не имеет значения.