单元测试中使用Mockito模拟对象

}

值得注意的是,对于final类、匿名类和Java的基本类型是无法进行Mock的。

设定Mock对象的期望值行为及返回值

有两种通用基础设定写法:

  1. when(...).thenReturn(...);

  2. doReturn(...).when(...).someMethod();

但是,doReturn(...).when(mockObj.someMethod());会抛异常。

@Test

public void testMockClass() {

// 对方法设定返回值,也就是设置数据桩

when(mockServiceImpl.findUserByUserName(“tom”)).thenReturn(new User(“tom”, “1234”));

doReturn(true).when(mockServiceImpl).hasMatchUser(“tom”, “1234”);

User user = mockServiceImpl.findUserByUserName(“tom”);

boolean isMatch = mockServiceImpl.hasMatchUser(“tom”, “1234”);

assertNotNull(user);

assertEquals(user.getUserName(), “tom”);

assertEquals(isMatch, true);

}

也值得注意的是,static和final修饰的方法无法进行设定的。

验证交互行为

Mock对象一旦建立便会自动记录自己的交互行为,所以,可以有选择地对其交互行为进行验证。

@Test

// 模拟接口UserService测试

public void testMockInterface() {

// 对方法设定返回值,也就是设置数据桩

when(mockUserService.findUserByUserName(“tom”)).thenReturn(new User(“tom”, “1234”));

doReturn(true).when(mockUserService).hasMatchUser(“tom”, “1234”);

// 对void方法进行方法预期设定

User u = new User(“John”, “1234”);

doNothing().when(mockUserService).registerUser(u);

// 执行方法调用

User user = mockUserService.findUserByUserName(“tom”);

boolean isMatch = mockUserService.hasMatchUser(“tom”, “1234”);

mockUserService.registerUser(u);

assertNotNull(user);

assertEquals(user.getUserName(), “tom”);

assertEquals(isMatch, true);

// 验证交互行为

verify(mockUserService).findUserByUserName(“tom”);

// 验证方法只调用一次

verify(mockUserService, times(1)).findUserByUserName(“tom”);

// 验证方法至少调用一次

verify(mockUserService, atLeastOnce()).findUserByUserName(“tom”);

verify(mockUserService, atLeast(1)).findUserByUserName(“tom”);

// 验证方法至多调用一次

verify(mockUserService, atMost(1)).findUserByUserName(“tom”);

verify(mockUserService).hasMatchUser(“tom”, “1234”);

verify(mockUserService).registerUser(u);

}

对Service层进行单元测试


同常主要Java Web应用分Controller,Service,DAO基本三层来进行开发。

接下来通过使用Mockito框架对Service进单元测试。

Domain领域对象:

public class Product {

}

DAO数据连接层:

public interface ProductDao {

int getAvailableProducts(Product product);

int orderProduct(Product product, int orderedQuantity);

}

Service业务逻辑层:

public class ProductService {

private ProductDao productDao;

public boolean buy(Product product, int orderedQuantity) {

int availableQuantity = productDao.getAvailableProducts(product);

if (orderedQuantity > availableQuantity) {

return false;

}

productDao.orderProduct(product, orderedQuantity);

return true;

}

}

Service测试用例:

public class ProductServiceTest {

private ProductDao productDao;

@Before

public void setupMock() {

//模拟Dao层

productDao = mock(ProductDao.class);

}

@Test

public void testBuy() {

int availableQuantity = 30;

Product product = new Product();

ProductService productService = new ProductService();

//设置数据桩

when(productDao.getAvailableProducts(product)).thenReturn(availableQuantity);

//doReturn(availableQuantity).when(productDao).getAvailableProducts(product);

//这写法不行

//doReturn(availableQuantity).when(productDao.getAvailableProducts(product));

//通过Spring测试框架提供的工具类为目标对象私有属性设值,这样就不用ProductDao另建setProductDao()方法

ReflectionTestUtils.setField(productService, “productDao”, productDao);

Assert.assertFalse(productService.buy(product, 31));

Assert.assertTrue(productService.buy(product, 3));

//验证交互行为

verify(productDao).orderProduct(product, 3);

verify(productDao, times(2)).getAvailableProducts(product);

}

}

测试用例中,用到Spring test框架的ReflectionTestUtils,它可以为目标对象非公有属性设值,或调用非公有setter方法,方便测试过程中使用。

为了使用ReflectionTestUtils,需要向pom.xml添加下面的依赖

org.springframework

spring-test

3.0.5.RELEASE

test

org.springframework

spring-core

3.0.5.RELEASE

test

commons-logging

commons-logging

1.2

test

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值