JavaMockito的使用

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层

@Service
public 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.编写一个基本的测试方法
@Test
public 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.测试一个保存方法,带参数匹配和返回处理
@Test
public 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处理
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值