Как понять почему тесты не отрабатывают?
От: peer  
Дата: 06.07.22 14:18
Оценка:
Есть такой нехитрый код в контроллере

public class CarController : CarControllerBase
{
        private readonly IFeatureGetCarById _featureGetCarById;       

        public CarController (IFeatureGetCarById featureGetCarById)
        {
            _featureGetCarById= featureGetCarById;
        }

   public async Task<IActionResult> GetCarById(
            CancellationToken cancellationToken,
            [Required] Guid carId,
            int? version,
            [FromServices] IFeatureGetCarById featureGetCarById)
{
    return version.HasValue ? 
                Ok(await featureGetCarById.GetCarByIdForVersion(carId, version.Value, cancellationToken)) : 
                Ok(await featureGetCarById.GetCarByIdAsync(carId, cancellationToken));
}



и есть такой код в тесте.
Тест заходит в метод контроллера GetCarById но внутрь GetCarByIdForVersion или GetCarByIdAsync уже не заходит.
В ошибку не падает,возвращает просто null и 200
Как понять в чем проблема?
Есть подозрение что надо мокать еще внутри сервиса FeatureGetCarById что в конструктор инжектится.
А там среди прочих сервисов инжектится еще и DbContext.


    var mockIFeatureGetCarById  = new Mock<IFeatureGetCarById>();            
            
            CancellationToken cancellationToken = new CancellationToken();
            Guid carId = new Guid("1018917A-FDF1-EC11-A07B-A4C3F063C82D");
            int version = 2;

            mockFeatureGetCarById.Setup(feature => feature.GetCarByIdForVersion(carId, version, cancellationToken));
            mockFeatureGetCarById.Setup(feature => feature.GetCarByIdAsync(carId, cancellationToken));

            
            var carController = new CarController(mockIFeatureGetCarById.Object);
            
            var result = await carController.GetCarById(cancellationToken, carId , version, mockIFeatureGetCarById.Object);
Re: Как понять почему тесты не отрабатывают?
От: maxkar  
Дата: 09.07.22 14:57
Оценка: 9 (1)
Здравствуйте, peer, Вы писали:

P>и есть такой код в тесте.

P>Тест заходит в метод контроллера GetCarById но внутрь GetCarByIdForVersion или GetCarByIdAsync уже не заходит.
P>В ошибку не падает,возвращает просто null и 200
P>Как понять в чем проблема?

А почему должен? И самое главное, как оно должно догадаться, куда именно заходить? Ведь может быть сотня реализаций IFeatureGetCarById. Как оно должно догадаться, какую реализацию вы имели в виду? В коде у вас мок. На моке метод вызывается. Возвращает то, что может вернуть. Вы ведь ему не говорите, что именно нужно вернуть при настройке мока

P>Есть подозрение что надо мокать еще внутри сервиса FeatureGetCarById что в конструктор инжектится.


Ну. Есть такой вариант, да. Но зачем? Что именно вы хотите протестировать в результате? Контроллер? Настраивайте правильно мок и тестируйте контроллер. И отдельно тестируйте реализацию IFeatureGetCarById. Тогда это будет два unit-теста. А иначе у вас будут тестироваться два и более произвольных класса вместе. При этом нет гарантии, что этот набор классов хоть как-то соответствует реальной системе (т.е. они сконфигурированы так же, как в приложении, что никто не написал другую реализацию IFeatureGetCarById и начал ее использовать и т.д.).

P>А там среди прочих сервисов инжектится еще и DbContext.


Отлично! Можно выделить интерфейс общения IFeatureGetCarByIdImpl и DBContext и мокать его. Или мокать DbContext. Но это все полумеры. Гораздо лучше было бы написать один интеграционный тест к приложению вместо кучи моков. Он сразу проверил бы контроллер, реализацию IFeatureGetCarByIdImpl, DbContext и все остальное.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.