Как проверить метод в модульном тестировании - PullRequest
1 голос
/ 30 марта 2020

У меня есть такой service, как показано ниже. Допустим, я хочу проверить метод Create(). Я прочитал, что в unit testing я должен проверить по comparing, counting и так далее. Как я мог тогда проверить мой Create() метод. Ужасно ли менять тип возвращаемого значения с void Create на bool Create, просто чтобы иметь возможность проверить вывод метода для целей тестирования, или это не идеальная идея? Вы можете что-то предложить?

public class CreateCarService : ICreateCarService
{
    private readonly ICarQuery _carQuery;
    private readonly ICarRepository _carRepository;

    public CreateCarService(ICarQuery carQuery, ICarRepository carRepository)
    {
        _carQuery = carQuery;
        _carRepository = carRepository;
    }

    public void Create(Car car)
    {
        if (car == null) throw new CusException(Error, "Car object cannot be null");

        if (_carQuery.IsLoginExist(car.Login))
            throw new CusException(Error, "Message1");

        if (_carQuery.IsEmailExist(car.Email))
            throw new CusException(Error, "Message1");

        _carRepository.Add(car);
    }
}

Ответы [ 3 ]

4 голосов
/ 30 марта 2020

Вы можете убедиться, что для любого действительного Car экземпляра Add метод был вызван только один раз, настроив поведение Moq для IsLoginExist и IsEmailExist метода с использованием Verify method

[TestFixture]
public class Test
{
    [Test]
    public void CreateCarServiceTest()
    {
        var carQueryMock = new Mock<ICarQuery>();
        var carRepositoryMock = new Mock<ICarRepository>();
        var createCarService = new CreateCarService(carQueryMock.Object, carRepositoryMock.Object);

        carQueryMock.Setup(c => c.IsLoginExist(It.IsAny<string>())).Returns(false);
        carQueryMock.Setup(c => c.IsEmailExist(It.IsAny<string>())).Returns(false);

        createCarService.Create(new Car());
        carRepositoryMock.Verify(c => c.Add(It.IsAny<Car>()), Times.Once);
    }
}

Также имеет смысл проверять отрицательные случаи, когда метод Create выдает исключение

[Test]
public void CreateCarNegativeTest()
{
    var carQueryMock = new Mock<ICarQuery>();
    var carRepositoryMock = new Mock<ICarRepository>();
    var createCarService = new CreateCarService(carQueryMock.Object, carRepositoryMock.Object);

    Assert.Throws<CusException>(() => createCarService.Create(null));

    carQueryMock.Setup(c => c.IsLoginExist(It.IsAny<string>())).Returns(true);
    Assert.Throws<CusException>(() => createCarService.Create(new Car()));

    carQueryMock.Setup(c => c.IsLoginExist(It.IsAny<string>())).Returns(false);
    carQueryMock.Setup(c => c.IsEmailExist(It.IsAny<string>())).Returns(true);
    Assert.Throws<CusException>(() => createCarService.Create(new Car()));
}

Вы можете разбить этот метод на разные тесты, чтобы иметь один Assert за тест или передать ему параметры.

1 голос
/ 30 марта 2020

Вы хотите проверить " ожидаемое поведение " тестируемого члена. Поскольку тестируемый элемент не возвращает проверяемого вывода и зависит от внешних абстракций, вы должны иметь возможность отслеживать взаимодействие тестируемого элемента с этими внешними абстракциями и проверять ожидаемое поведение

Один из таких примеров

public void CreateCarService_Create_Should_Add_Car() {    
    //Arrange
    Car car = new Car {
        Login = "Login",
        Email = "Email"
    };

    ICarQuery carQuery = Mock.Of<ICarQuery>();
    ICarRepository carRepository = Mock.Of<ICarRepository>();

    ICreateCarService subject = new CreateCarService(carQuery, carRepository);

    //Act
    subject.Create(car);

    //Assert
    Mock.Get(carRepository).Verify(_ => _.Add(car), Times.Once);
}

В приведенном выше примере безопасно проходит до конца тестируемого элемента, но предположим, что вы хотите проверить, что исключение выдается для случая с нулевым параметром.

public void CreateCarService_Create_Should_Throw_CusException_For_Null_Car() {    
    //Arrange        
    ICreateCarService subject = new CreateCarService(null, null);

    //Act
    Action act = ()=> subject.Create(null);

    //Assert
    var ex = Assert.Throws<CusException>(act);        
}

Вы хочу создать тесты для всех возможных путей через тестируемый член. Так что найдите время и просмотрите тестируемый предмет и определите возможные тестовые случаи. Организовать предмет для удовлетворения этих случаев и выполнить эти случаи для проверки ожидаемого поведения.

Ссылка Быстрый запуск Moq , чтобы получить лучшее понимание того, как использовать структуру Moq Mocking.

0 голосов
/ 30 марта 2020

Вам не нужно менять его на bool, просто чтобы проверить. Это можно сделать простым способом:

        [TestFixture]
        public class Test
        {
          CreateCarService createCarService;
          ICarRepository carRepositoryMock; 
        [Setup]
        public void InitializeTest()
        {
            var carQueryMock = new Mock<ICarQuery>();
            carRepositoryMock = new Mock<ICarRepository>();
            createCarService = new CreateCarService(carQueryMock.Object, carRepositoryMock.Object);
        }

        [Test]
        public void CreateCarShouldThrowIfNull() 
        { 
          //arrange
          Car car =null;

         //act and assert
         Assert.Throw<CustomException>(()=>
         {
            createCarService.CreateCar(car);
         });
        }
        [Test]
        public void CreateCarShouldThrowForInvalidLogin() 
        { 
          //arrange
          var car = new Car()
         {
            Login=null,
            Email="Email"
         };

         //act and assert
         Assert.Throw<CustomException>(()=>
         {
            createCarService.CreateCar(car);
         });
        }

и т. Д.

Вы можете использовать Assert.Throw для недопустимых автомобильных объектов или Assert.DoesNotThrow для допустимых автомобильных объектов. Наконец, вы можете проверить, был ли автомобиль добавлен в хранилище:

  [Test]
    public void CreateCarShouldAddCarToRepo() 
    { 
      //arrange
      var car = new Car()
     {
        Login="Login",
        Email="Email"
     };

     //act
        createCarService.CreateCar(car);

      var carRetrieved =carRepositoryMock.GetCar(car.id);//depending on your implementation
      //assert
      Assert.AreSame(car,carRetrieved);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...