【问题标题】:How to test these kinds of methods (from Service layer)如何测试这些方法(来自服务层)
【发布时间】:2014-12-23 15:42:08
【问题描述】:

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

我已经测试了几乎 100% 覆盖率的 CategoryDao。

现在我想测试 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));
    }

非常感谢您的帮助:)

最好的问候, 汤姆

【问题讨论】:

  • 这是一个很好的例子,说明为什么要使用构造函数注入而不是字段注入:您可以使用 Mockito 或 Spock 的模拟 DAO 创建服务对象并验证适当的交互。 (我还建议查看 Spring Data 而不是手写自己的 DAO 类。)

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


【解决方案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();
    }
}

【讨论】:

  • 好的,我理解你的做法。您能否提供一些示例测试,例如addCategory 还是 getCategories?谢谢你:)
  • 添加了 addCategory() 的测试用例
猜你喜欢
  • 2019-10-30
  • 1970-01-01
  • 2020-03-17
  • 2022-01-21
  • 2017-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多