2014-12-23 2 views
0

Я играю с Mockito и Spring MVC. Я пытаюсь написать модульные тесты для кода, который я только что написал.Как проверить эти методы (из уровня сервиса)

Это мой CategoryService класс:

@Service 
public class CategoryService { 

    @Autowired 
    @Qualifier("categoryDaoImpl") 
    private CategoryDao categoryDao; 

    public void addCategory(Category category) { 
     category.setId(getLastCategoryId() + 1); 
     categoryDao.addCategory(category); 
    } 

    public Category getCategoryById(int id) { 
     return categoryDao.getCategoryById(id); 
    } 

    public List<Category> getCategories() { 
     return categoryDao.getAllCategories(); 
    } 

    public int getCategoriesCount() { 
     return categoryDao.getCategoriesCount(); 
    } 

    public int getLastCategoryId() { 
     if (categoryDao.getAllCategories().size() == 0) { 
      return 0; 
     } 
     return Collections.max(categoryDao.getAllCategories()).getId(); 
    } 

    public CategoryDao getCategoryDao() { 
     return categoryDao; 
    } 

    public void setCategoryDao(CategoryDao categoryDao) { 
     this.categoryDao = categoryDao; 
    } 

Я уже опробовал CategoryDao с охватом почти 100%.

А теперь я хочу проверить CategoryService, но я не знаю, как проверить это, я имею в виду такие методы, как: addCategory, getCategoryById, getAllCategories, getCategoiesCount и т.д.

Они просто говорить с шаблоном DAO, но что, если другой человек изменит свою логику? Я был бы рад, если бы вы сказали мне или показали, как писать тесты для таких коротких методов.

Что касается CategoryService, то я только написал тесты для getLastCategoryId():

@Test 
    public void shouldGetLastCategoryIdWhenListIsEmpty() { 
     //given 
     List<Category> list = new ArrayList<Category>(); 
     Mockito.when(categoryDao.getAllCategories()).thenReturn(list); 

     //when 
     int lastCategoryId = categoryService.getLastCategoryId(); 

     //then 
     assertThat(lastCategoryId, is(0)); 
    } 

    @Test 
    public void shouldGetLastCategoryIdWhenListIsNotEmpty() { 
     //given 
     List<Category> list = new ArrayList<Category>(); 
     list.add(new Category(1, "a", "a")); 
     list.add(new Category(3, "a", "a")); 
     list.add(new Category(6, "a", "a")); 

     Mockito.when(categoryDao.getAllCategories()).thenReturn(list); 

     //when 
     int lastCategoryId = categoryService.getLastCategoryId(); 

     //then 
     assertThat(lastCategoryId, is(6)); 
    } 

Большое спасибо за помощь :)

С уважением, Том

+0

Это отличный пример того, почему использовать инъекцию конструктора вместо инъекции поля: вы можете просто создать служебный объект с помощью макета DAO от Mockito или Spock и проверить соответствующие взаимодействия. (Я бы также предложил посмотреть Spring Data вместо написания собственных классов DAO.) – chrylis

ответ

1

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

См., Например, Метод addCategory (Категория c) добавляет категорию. Это можно проверить, подтвердив, что метод categoryDao.addCategory() вызывается с объектом категории, который имеет необходимые свойства. В этом случае идентификатор должен быть установлен в lastCategoryId. Проверка может быть просто выполнена путем создания шпиона класса CategoryDao (проще было бы использовать сторонние библиотеки, такие как mockito.

В тестовых случаях для методов getCategoryById(), getCategories() и getCategoriesCount() можно было убедиться, что возвращаемые значения являются те, которые возвращаются dao.

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

Вот один тестовый пример для addCategory()

public class CategoryServiceTest { 
    private CategoryService service; 
    private CategoryDaoSpy daoSpy; 

    @Before 
    public void setUp() { 
     service = new CategoryService(); 
     daoSpy = new CategoryDaoSpy(); 
     service.setCategoryDao(daoSpy); 
    } 


    @Test 
    public void shouldSaveCategoryWhenCategoryPassed() { 
     Category category = new Category(); 
     service.addCategory(category); 

     assertEquals(daoSpy.getAddCategoryCallCount(), 1); 
     assertEquals(daoSpy.getCategories().size(), 1); 
     assertEquals(daoSpy.getCategories().get(0).getId(), 1); 
    } 

} 

public class CategoryDaoSpy extends CategoryDao { 

    private int addCategoryCallCount = 0; 
    private List<Category> categories = new ArrayList<>(); 

    @Override 
    public void addCategory(Category category) { 
     this.addCategoryCallCount++; 
     categories.add(category); 
    } 

    public int getAddCategoryCallCount() { 
     return addCategoryCallCount; 
    } 

    public List<Category> getCategories() { 
     return categories; 
    } 

    @Override 
    public List<Category> getAllCategories() { 
     return Collections.emptyList(); 
    } 
} 
+0

ОК, я понимаю ваш подход. Не могли бы вы предоставить некоторые примеры тестов, например. addCategory или getCategories? спасибо :) – tomdavies

+0

Добавлен тестовый пример для addCategory() –

+0

Спасибо большое :) – tomdavies

Смежные вопросы