junit单元测试3:springockito
接http://baowp.iteye.com/blog/1988249,前文举例了一个使用mockito在spring管理的实例中注入一个mock对象的情况,但是仅限于直接引用的对象且要写MockitoAnnotations.initMocks(this)使其生效。
如何能够与spring结合得更深,就像是注入spring bean一样地注入mock对象,这样对于写包含外部依赖的单元测试会完美些。如下:
单例类,测的是bookService.list():
package com.iteye.baowp.domain.service; import com.iteye.baowp.domain.entity.BookEntity; import com.iteye.baowp.domain.reference.RemoteService; import com.iteye.baowp.domain.repository.BookRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.kubek2k.springockito.annotations.ReplaceWithMock; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * Created with IntelliJ IDEA. * User: baowp * Date: 12/7/13 * Time: 10:26 AM */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"BookServiceTest-context.xml", "spring-mockito.xml"}) public class SpringockitoXmlMockTest { @Resource private BookService bookService; @ReplaceWithMock @Resource private RemoteService remoteService; @ReplaceWithMock @Resource private BookRepository bookRepository; @Test public void testList() { //构造一个结果集 BookEntity book = new BookEntity(); book.setTitle("title"); book.setPrice(1.1f); List<BookEntity> books = new ArrayList<BookEntity>(); books.add(book); {//设置方法返回的期望结果 when(bookRepository.list()).thenReturn(Collections.<BookEntity>emptyList()); when(remoteService.remoteBooks()).thenReturn(books); } List<BookEntity> list = bookService.list(); assertEquals(1, list.size()); assertSame(book, list.get(0)); verify(bookRepository).list();//断言bookRespotitory.list()被调用一次 verify(remoteService).remoteBooks();//断言remoteService.remoteBooks()被调用一次 } }
功能实现类,里面注入的两个bean在上文中调用时已经被mock,将返回期望的结果:
package com.iteye.baowp.domain.service.impl; import com.iteye.baowp.domain.entity.BookEntity; import com.iteye.baowp.domain.reference.RemoteService; import com.iteye.baowp.domain.repository.BookRepository; import com.iteye.baowp.domain.service.BookService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; /** * Created with IntelliJ IDEA. * User: baowp * Date: 11/27/13 * Time: 3:04 PM */ @Service("bookService") public class BookServiceImpl implements BookService { @Resource private BookRepository bookRepository; @Resource private RemoteService remoteService; public List<BookEntity> list() { List<BookEntity> list = bookRepository.list(); if (list.isEmpty()) { list = remoteService.remoteBooks(); } return list; } }
springockito圆满地解决了上篇中提到的缺陷,该maven依赖会自动引入mockito。@ReplaceWithMock @Resource联合标注的为mock对象,并注入为spring bean,无论它被哪个spring bean引用(包括间接引用),都能够正确注入。
BookServiceTest-context.xml是一个正常的spring配置文件,spring-mockito.xml是mock bean的配置文件,加载这两个配置文件的时候,如果有同名beanId将以mock bean为准。
spring-mockito.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mockito="http://www.mockito.org/spring/mockito" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tip/springockito/src/main/resources/spring/mockito.xsd"> <mockito:mock id="remoteService" class="com.iteye.baowp.domain.reference.RemoteService" /> <mockito:mock id="bookRepository" class="com.iteye.baowp.domain.repository.BookRepository" /> </beans>
maven usage:
<dependency> <groupId>org.kubek2k</groupId> <artifactId>springockito</artifactId> <version>1.0.9</version> <scope>test</scope> </dependency>
单元测试预期已经达到,但是每次写单测多出来一个spring-mockito.xml的配置文件,有一个小冗余。
上一篇: mockito+testng Mock Redis
下一篇: NSubstitute完全手册索引
推荐阅读
-
junit单元测试3:springockito
-
Junit单元测试工具快速入门
-
Java单元测试工具 Junit4入门使用教程
-
单元测试工具Junit
-
Junit5单元测试的常用注解
-
Java学习记录:纠错Junit单元测试遇到的initializationerror:method initializationerror not found
-
使用junit进行单元测试时报错Invalid bound statement (not found)
-
######ssh:Junit遇到initializationError(知识点:Junit测试3要素:public、void、无参)==解决:检查所有方法的注解。是否添加正确
-
java单元测试JUnit框架原理与用法实例教程
-
JUnit单元测试入门必看篇