Задать вопрос
@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();
    }

}
  • Вопрос задан
  • 289 просмотров
Подписаться 3 Простой 2 комментария
Решения вопроса 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
Сеньор-помидор
Не думаю, что это имеет смысл, посколько суть теста - проверять корректность кода. Эти тесты генерируются так, что они проходят с текущим кодом. Так что подходят они только как защита от изменений поведения при рефакторинге
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы