【发布时间】:2018-11-18 10:24:35
【问题描述】:
我正在使用 Mockito 测试我的 API 服务 REST,我正在使用 Spring Framework 4.1.4.RELEASE 和 Mockito 1.9.5。
我有一个用于访问唯一 DAOImpl 的多品牌系统(每个品牌都是唯一的 @PersistenceContext(unitname = "emX"),其中“X”是品牌字符),每个品牌都从抽象 DaoBase 类(谁实现一个名为 Dao 的接口),我通过以下方式从 Service 类获取组件访问:
applicationContext.getBean(qualifier.concat(brand.name()), clazz)
(以 qualifier.concat(brand.name()) its = "DaoA" 为例)
这是结构:
- es.app.service
- ServiceClass.java 调用 DaoFactory 获取 Impl。
- es.app.dao
- Dao.java
- DaoBase.java 实现 Dao
- DaoFactory.java
- es.app.dao.impl
- DaoAImpl.java 扩展了 DaoBase @Repository("DaoA")
- DaoBImpl.java 扩展了 DaoBase @Repository("DaoB")
- DaoCImpl.java 扩展了 DaoBase @Repository("DaoC")
- DaoDImpl.java 扩展了 DaoBase @Repository("DaoD")
然后我有一个关于测试包的测试类
- es.app.service
ServiceClassTest.java
我在这里为每个类放了一点代码:
DaoFactory.java
@Component
public class DaoFactory implements Serializable, ApplicationContextAware{
private ApplicationContext ctx;
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = LoggerFactory.getLogger(DaoFactory.class);
public Dao getInstance(GroupBrand brand){
switch(brand){
case A:
case B:
case C:
case D:
return (Dao)getComponent("Dao",Dao.class, brand);
default: break;
}
throw new IllegalArgumentException("Unsupported brand ".concat(brand.name()));
}
private Object getComponent(String qualifier, Class<?> clazz, GroupBrand brand){
Object instance = ctx.getBean(qualifier.concat(brand.name()), clazz);
if(Utils.isNull(instance)){
throw new IllegalArgumentException("Unkown business bean with Qualifier: ".concat(qualifier.concat(brand.name())).concat("type: ").concat(clazz.getName()));
}
LOGGER.debug("DAO retrived: " + qualifier.concat(brand.name()) +" class: " + clazz.getName());
return instance;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ctx = applicationContext;
}
}
DaoBase.java
public abstract class DaoBase implements Dao {
protected abstract EntityManager getEntityManager();
private static final String EMPTY = "";
private static final Logger LOGGER = LoggerFactory.getLogger(DaoBase.class);
@Override
public Boolean findAvailability(GroupBrand marca, String code) {
EntityManager em = getEntityManager();
Query query = em.createNamedQuery("Conn.isAvailability");
query.setParameter(1, code);
query.setParameter(2, marca.toCharCode());
try{
String value = (String)query.getSingleResult();
if(value.equalsIgnoreCase("S")){
return true;
}else{
return false;
}
}catch(Exception ex){
return Boolean.FALSE;
}
}
}
DaoAImpl.java
@Repository("DaoA")
public class DaoAImpl extends DaoBase {
@PersistenceContext(unitName = "emA")
private EntityManager em;
@Override
@Transactional("A")
public Boolean findAvailability(GroupBrand marca, String code) {
return super.findAvailability(marca, code);
}
}
ServiceClass.java
@Override
public boolean isAvailable(GroupBrand brand, String code){
Boolean available = getDMSQisAvailability(brand, code);
return available;
}
protected Boolean isAvailability(GroupBrand marca, String kvps){
boolean value = daoFactory.getInstance(marca).findDMSQisAvailability(marca, code);
return value;
}
ServiceClassTest.java
@InjectMocks
@Autowired
@Qualifier("serviceClass")
private ServiceClass srv;
@Autowired
@Qualifier("DaoFactory")
protected DaoFactory daoFactory;
@Mock
protected Dao dao;
@Override
public void mockBehaivors() throws ResourceException, ResourceNotFoundException, ApiException {
MockitoAnnotations.initMocks(this);
dao = daoFactory.getInstance(marca);
when(dao.findAvailability(any(GroupBrand.class), any(String.class))).thenReturn(Boolean.TRUE);
}
@Test
public void isAvailableTest() throws ResourceException, Exception{
Boolean available = srv.isAvailable(GroupBrand.A, "CODE");
}
我需要覆盖 ServiceClass.java 类,但我不能模拟来自这个 Test 类的 Dao 调用总是做真正的调用并且不返回我在“何时”定义的内容,其他测试工作但不使用 dao 访问。
谁能帮帮我?
(为我糟糕的英语道歉)..
问候,
【问题讨论】:
-
你试过下面的解决方案了吗!