@turdubekov
Студент

Стоит ли плагину доверят писать unit-тесты?

При изучении тестирование наткнулся на плагин
Diffblue
, который пишет тесты.
Сам в тестировании пока-что ничего не понимаю, чтобы оценить результат. Прошу оценить работу
результат работы плагина.

Обычный сервис класс:
@Service
@Slf4j
public class ProductService {

	@Autowired
	private   ProductRepository repo;

	public List<Product> listAll(String keyword) {
		if (keyword != null) {
			log.info("Поиск продукта по ключевому слову {}", keyword);
			return repo.search(keyword);
		}
		return repo.findAll();
	}
	
	public void save(Product product) {
		if (product != null){
			repo.save(product);
		}else {
			log.error("Продукт не может быть пустым!");
		}
	}
	
	public Product get(Long id) {
		if (repo.findById(id).isPresent()){
			return repo.findById(id).get();
		}
		log.error("Продукт не найден");
		return null;
	}
	
	public void delete(Long id) {
		log.warn("Продукт по id {} удален", id);
		repo.deleteById(id);
	}

	public List<Product> getAll(){
		return repo.findAll();
	}

}


тест:
@ContextConfiguration(classes = {ProductService.class})
@ExtendWith(SpringExtension.class)
class ProductServiceTest {
    @MockBean
    private ProductRepository productRepository;

    @Autowired
    private ProductService productService;

    @Test
    void testListAll() {
        ArrayList<Product> productList = new ArrayList<Product>();
        when(this.productRepository.search((String) any())).thenReturn(productList);
        List<Product> actualListAllResult = this.productService.listAll("Keyword");
        assertSame(productList, actualListAllResult);
        assertTrue(actualListAllResult.isEmpty());
        verify(this.productRepository).search((String) any());
        assertTrue(this.productService.getAll().isEmpty());
    }



    @Test
    void testSave() {
        Product product = new Product();
        product.setPrice(10.0);
        product.setId(123L);
        product.setName("Name");
        product.setCategoryList(new ArrayList<Category>());
        product.setDescription("The characteristics of someone or something");
        product.setCategory2("Category2");
        when(this.productRepository.save((Product) any())).thenReturn(product);

        Product product1 = new Product();
        product1.setPrice(10.0);
        product1.setId(123L);
        product1.setName("Name");
        product1.setCategoryList(new ArrayList<Category>());
        product1.setDescription("The characteristics of someone or something");
        product1.setCategory2("Category2");
        this.productService.save(product1);
        verify(this.productRepository).save((Product) any());
        assertTrue(this.productService.getAll().isEmpty());
    }


    @Test
    void testGet() {
        Product product = new Product();
        product.setPrice(10.0);
        product.setId(123L);
        product.setName("Name");
        product.setCategoryList(new ArrayList<Category>());
        product.setDescription("The characteristics of someone or something");
        product.setCategory2("Category2");
        Optional<Product> ofResult = Optional.<Product>of(product);
        when(this.productRepository.findById((Long) any())).thenReturn(ofResult);
        assertSame(product, this.productService.get(123L));
        verify(this.productRepository, atLeast(1)).findById((Long) any());
        assertTrue(this.productService.getAll().isEmpty());
    }



    @Test
    void testDelete() {
        doNothing().when(this.productRepository).deleteById((Long) any());
        this.productService.delete(123L);
        verify(this.productRepository).deleteById((Long) any());
        assertTrue(this.productService.getAll().isEmpty());
    }



    @Test
    void testGetAll() {
        ArrayList<Product> productList = new ArrayList<Product>();
        when(this.productRepository.findAll()).thenReturn(productList);
        List<Product> actualAll = this.productService.getAll();
        assertSame(productList, actualAll);
        assertTrue(actualAll.isEmpty());
        verify(this.productRepository).findAll();
    }

}
  • Вопрос задан
  • 287 просмотров
Решения вопроса 2
Стоит придерживаться правила не доверять не одному автоматическому инструменту до того момента, пока не будете понимать как он работает под капотом и какие тесты генерирует. В таком случае сама генерация тестов это бесполезное занятие, так как вы даже не знаете что именно этот код тестирует и как.
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
Проверим один тест.
// Какую концепцию проверяем?
   // Это не просто проверка функции ListAll, это проверка какой-то концепции кода
   // Варианты.
   // 1. Пустой listAll() даёт пустой список.
   // 2. Непустой listAll() даёт непустой список.
    void testListAll() {
        ArrayList<Product> productList = new ArrayList<Product>();
        // Проводим поиск в списке — что в этот список вносится?
        // И не будет ли физической зависимости тестов друг от друга?
        // И для чего вообще нужен этот search, если мы listAll тестируем?
        // Что такое ProductRepository и он вообще проверен?
        when(this.productRepository.search((String) any())).thenReturn(productList);
        // Ну, хорошо.
        List<Product> actualListAllResult = this.productService.listAll("Keyword");
        // Отказ, они не same: первый мы только что создали, а второй откуда-то пришёл.
        assertSame(productList, actualListAllResult);
        // Получается, что концепция — поиск, когда ничего не находится?
        assertTrue(actualListAllResult.isEmpty());
        verify(this.productRepository).search((String) any());
        // Получается, единственная концепция, которую мы тестируем,— поиск в пустом списке даёт пустоту
        // (и та некорректная из-за assertSame).
        assertTrue(this.productService.getAll().isEmpty());
    }


Ну что, понятно, что или фтопку такие инструменты, или нужно их серьёзно осваивать, прежде чем будут приносить хоть какие-то результаты?
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Djaler
@Djaler
Сеньор-помидор
Не думаю, что это имеет смысл, посколько суть теста - проверять корректность кода. Эти тесты генерируются так, что они проходят с текущим кодом. Так что подходят они только как защита от изменений поведения при рефакторинге
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы