Рубрики
Без рубрики

Как Выполнить Модульный Тест, Например профессионал

Что такое модульное тестирование ❓ 📦 Тестирование “единицы” в системе отдельно от других единиц…. С пометкой java, веб-разработчик, учебник, программирование.

Тестирование ” блока ” в системе отдельно от других блоков.

Но Что Означает Единица Измерения ❓

Существует много разных мнений относительно ответа на этот вопрос.

  • Некоторые люди говорят, что единица – это функция, некоторые говорят, что это класс.

🟢 Однако определение, которое я нахожу наиболее логичным, – это определение, описывающее единицу как “поведение” системы.

  • Это сценарий, который имеет значение в бизнес-логике.

  • Например, создайте новую отправку, используя входные данные клиента, и сохраните их в базе данных.

    • на самом деле не спасать, а подделывать (издеваться), мы увидим это немного позже

Но Почему Описание Поведения Кажется Наиболее Логичным ❓

Тесты были бы ближе к реальной жизни ✔️

Вы бы не стали писать бесполезные тесты. (например, бесполезная проверка нулевого указателя) ✔️

Мы можем реорганизовать наш код, не нарушая тесты, так как мы тестируем выходные данные устройства, а не его внутреннюю работу ✔️

Однако есть некоторые вещи, которые мы, возможно, не захотим тестировать в подразделении 🔴

Как что?

Чаще всего – зависимость от внешнего мира.

  • Подключение к базе данных (дайте мне запись с этим идентификатором)
  • Вызовы API (вызовите API Twitter и получите все мои твиты)

Эти зависимости нам нужны для издеваться . Издевательство – это определение того, как зависимость должна действовать в определенных условиях.

  • о, дорогое подключение к базе данных, пожалуйста, верните этот объект, если ваш метод x был вызван с параметром y.

Давайте посмотрим на пример ⚙️

У нас есть класс отгрузки 📦

@RequiredArgsConstructor  
public class Shipment {  
   private final String productCode;  
   private final String owner;  
   private final int count;  
}

Хранилище отгрузок для операций с базой данных 🗃

public class ShipmentRepository {  
    public Optional findShipment(String owner, String productCode) {  
        // mock method  
  return Optional.empty();  
    }  
    public void save(Shipment shipment) {  
        // mock method  
  }  
}

Служба проверки подлинности 🔍

public class VerificationService {  
    public boolean shipmentIsntValid(String owner, String productCode, int count) {  
        return owner.isEmpty()  
                || productCode.isEmpty()  
                || count < 0;  
    }  
}

Служба доставки грузов 🥋

@RequiredArgsConstructor  
public class ShipmentService {  
    private final VerificationService verificationService;  
    private final ShipmentRepository shipmentRepository;  

    public String createAndSaveShipment(String owner, String productCode, int count){  
        if (verificationService.shipmentIsntValid(owner, productCode, count))  
            return "Shipment isn't valid";  
        if (shipmentExistInDB(owner, productCode))  
            return "Shipment Not Found";  
        createNewShipment(owner, productCode, count);  
        return "Shipment Is Created";  
    }  
    private void createNewShipment(String owner, String productCode, int count) {  
        Shipment shipment = new Shipment(owner, productCode, count);  
        shipmentRepository.save(shipment);  
    }  
    public boolean shipmentExistInDB(String owner, String productCode) {  
        return shipmentRepository.findShipment(owner, productCode).isPresent();  
    }  
}

Для модульного тестирования мы будем использовать Junit 5 и Mockito.

Давайте рассмотрим плохой пример модульных тестов ❌

@ExtendWith(MockitoExtension.class)  
public class UniTestTests {  
    @Mock  
  ShipmentRepository shipmentRepo;  
    @Test  
  public void givenData_DetectValidity(){  
        VerificationService verificationService = new VerificationService();  
        boolean result = verificationService.shipmentIsntValid("jhon", "3HFF", 2);  
        assertFalse(result);  
    }  
    @Test  
  public void givenData_DetectShipmentExistsInDB(){  
        ShipmentService shipmentService = new ShipmentService(new VerificationService(), shipmentRepo);  
        Shipment shipment = new Shipment("ahmed", "3HKK", 4);  
        doReturn(Optional.of(shipment)).when(shipmentRepo).findShipment("ahmed", "3HKK");  

        boolean result = shipmentService.shipmentExistInDB("ahmed", "3HKK");  
        assertTrue(result);  
    }  
}

Почему эти плохие модульные тесты? Важно

  • Служба отправки и служба проверки – это два тесно связанных метода, которые работают вместе для создания единого поведения (добавление новой отправки).
  • Однако мы тестируем их изолированно, как в отдельных тестах.

Теперь давайте рассмотрим хороший пример модульного тестирования ✅

@ExtendWith(MockitoExtension.class)  
public class UniTestTests {  
    @Mock  
  ShipmentRepository shipmentRepo;  
    @Test  
  public void givenShipmentData_CreateNewShipment(){  
        VerificationService verificationService = new VerificationService();  
        ShipmentService shipmentService = new ShipmentService(verificationService, shipmentRepo);  

        doReturn(Optional.empty()).when(shipmentRepo).findShipment("jalil", "3HXX");  
        doNothing().when(shipmentRepo).save(any());  

        String result = shipmentService.createAndSaveShipment("jalil", "3HXX", 10);  
        assertEquals("Shipment Is Created", result);  
    }  
}

Подведем итог в нескольких словах 🖋

Модульный тест предназначен для проверки поведения функций в системе. Это может быть набор классов и функций, взаимодействующих вместе для создания такого поведения.

Исходный код на 🔗 GitHub

Оригинал: “https://dev.to/jarjanazy/how-to-unit-test-like-a-pro-59kj”