JavaMockito的使用

来源:互联网 发布:苹果微信加附近人软件 编辑:程序博客网 时间:2024/06/17 16:13

JavaMockito的使用

  • 我们在写单元测试的时候,有时候不需要去检验某些组件是否正确,我们会默认这些组件正确的情况下测试其他组件,这时候我们可以使用Mocks框架代替其他组件,继续进行单元测试。
  • 模拟场景是Mock Spring-data-mongodb的MongoRepository,测试Service
  • Mockito官网也有非常完善的文档:
    http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html

在maven工程中添加Mockito依赖

<dependency>    <groupId>org.mockito</groupId>    <artifactId>mockito-all</artifactId>    <version>1.10.19</version>    <scope>test</scope></dependency>

测试的Model

@Document(collection = "user")public class MongoUser {    @Id    private String id;    @Indexed    @Field(value = "name")    private String name;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}

Mock的Repository

public interface MongoUserDao extends MongoRepository<MongoUser, String> {    List<MongoUser> findByName(String name);}

测试的Service层

@Servicepublic class UserService {    @Autowired    private MongoUserDao mongoUserDao;    public Observable<List<MongoUser>> findMongoUserByName(String name) {        Observable<List<MongoUser>> ob = Observable.create(observer -> {            try {                List<MongoUser> list = mongoUserDao.findByName(name);                observer.onNext(list);                observer.onCompleted();            } catch (Exception e) {                e.printStackTrace();                observer.onError(e);            }        });        return ob.subscribeOn(Schedulers.io());    }    public Observable<MongoUser> saveMongoUser(MongoUser mongoUser) {        Observable<MongoUser> ob = Observable.create(observer -> {            try {                MongoUser saved = mongoUserDao.save(mongoUser);                observer.onNext(saved);                observer.onCompleted();            } catch (Exception e) {                e.printStackTrace();                observer.onError(e);            }        });        return ob.subscribeOn(Schedulers.io());    }}

单元测试Mock MongoRepository测试UserService

1.Mock Repository

import static org.mockito.Mockito.*; // 静态导入导入Mockito的内置方法@RunWith(SpringJUnit4ClassRunner.class)@SpringApplicationConfiguration(classes = TestConfig.class)public class UserServiceMockTest {    @InjectMocks // 将Mock的mongoUserDao注入到Service中    @Autowired    private UserService service;    @Mock //Mock Repository    private MongoUserDao mongoUserDao;    @Rule    public ExpectedException expectedException = ExpectedException.none();    @Before    public void setUp(){        // 在使用@Mock注解时必须初始化Mocks        MockitoAnnotations.initMocks(this);    }    @Test    public void testGetMongoUser() {}    @Test    public void testSaveMongoUser() {}  }

关于上面代码的操作步骤:

# 1. mock repository对象    @Mock //Mock Repository    private MongoUserDao mongoUserDao;# 2. 将mock的对象注入到service之中    @InjectMocks // 将Mock的mongoUserDao注入到Service中    @Autowired    private UserService service;# 3. 使用@Mock注解时必须初始化注解    @Before //表示在测试方法调用前执行    public void setUp(){        // 初始化Mock注解        MockitoAnnotations.initMocks(this);    }# 4. @Rule实现测试单元对异常的判断    @Rule    public ExpectedException expectedException = ExpectedException.none();  

2.编写一个基本的测试方法

@Testpublic void testGetMongoUser() {    // 1. 先初始化一个我们定义的fake的返回的集合    List<MongoUser> list = new ArrayList<MongoUser>();    MongoUser user = new MongoUser();    user.setId(UUID.randomUUID().toString());    user.setName("user");    list.add(user);    // stubbing mongoUserDao当执行findByName(str)时,anyString()表示传入任意一个String类型的数据    // 就返回我们定义的fake的集合    when(mongoUserDao.findByName(anyString())).thenReturn(list);    // stubbing 当传入一个null参数时,抛出空指针异常    when(mongoUserDao.findByName(null)).thenThrow(            new NullPointerException("username cannot be null"));    //测试service方法    List<MongoUser> listRs = service.findMongoUserByName("user")            .toBlocking().first();    // 验证传入的参数是否是stubbing时matcher的参数    verify(mongoUserDao).findByName(anyString());    // 断言方法返回不为null    Assert.assertNotNull(listRs);    // 断言返回的集合是我们定义的集合    Assert.assertTrue(listRs.containsAll(list));    // 预言下面会抛出NullPointerException    expectedException.expect(NullPointerException.class);    // 预言抛出的异常信息包含 username cannot be null    expectedException.expectMessage("username cannot be null");    // 传入null会抛出异常    service.findMongoUserByName(null).toBlocking().first();}

3.测试一个保存方法,带参数匹配和返回处理

@Testpublic void testSaveMongoUser() {    // 定义一个数组保存save方法生成的id    String[] ids = new String[1];    // stubbing mongoUserDao当执行save方法并传入一个MongoUser对象时    when(mongoUserDao.save(argThat(new ArgumentMatcher<MongoUser>() {        // 匹配传入的参数为一个MongoUser对象        @Override        public boolean matches(Object argument) {            return argument instanceof MongoUser;        }    }))).thenAnswer(new Answer<MongoUser>() {         // 返回mock的保存后的MongoUser对象带ID信息,并将ID保存在ids数组中        @Override        public MongoUser answer(InvocationOnMock invocation)                throws Throwable {            MongoUser user = invocation.getArgumentAt(0, MongoUser.class);            user.setId(ids[0] = UUID.randomUUID().toString());            return user;        }    });    //测试保存方法    MongoUser mongoUser = new MongoUser();    mongoUser.setName("test");    MongoUser saved = service.saveMongoUser(mongoUser).toBlocking().first();    //验证保存对象是否正确    Assert.assertNotNull(saved);    Assert.assertEquals(mongoUser.getName(), saved.getName());    Assert.assertEquals(ids[0], saved.getId());}

至此,通过使用mock框架,我们就可以在不使用实际配置数据源的情况下,就可以测试我们的Service处理

0 0
原创粉丝点击