如何测试这些方法(来自服务层)

时间:2014-12-23 15:42:09

标签: spring unit-testing spring-mvc junit mockito

我正在摆弄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));
    }

非常感谢您的帮助:)

祝你好运, 汤姆

1 个答案:

答案 0 :(得分:1)

您需要验证服务方法是否按照合同行事,即使将来修改它们也是如此。

例如addCategory(Category c)方法添加类别。这可以通过验证使用具有所需属性集的类别对象调用categoryDao.addCategory()方法来验证。在这种情况下,id应设置为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();
    }
}