服务impl

时间:2018-06-08 11:05:01

标签: spring mockito

我正在使用Mockito来测试我的API服务REST,我正在使用Spring Framework 4.1.4.RELEASE和Mockito 1.9.5。

我有一个多品牌系统可以访问独特的DAOImpl(每个品牌都有独特的@PersistenceContext(unitname =“emX”),其中“X”是品牌char),每个品牌都延伸自抽象的DaoBase类(谁的实施)一个名为Dao的接口,我从Service类访问,通过以下方式获取组件:

applicationContext.getBean(qualifier.concat(brand.name()),clazz)

(例如qualifier.concat(brand.name())其=“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调用总是进行真正的调用而不返回我在“when”上定义的内容,其他测试有效,但未使用dao访问。

任何人都可以帮助我?

(为我可怜的英语道歉)..

此致

2 个答案:

答案 0 :(得分:1)

至少我找到了解决问题的方法,

当调用 getInstance()时,我必须模拟 DaoFactory 我返回 Dao 类的模拟。

类测试它是这样的:

@InjectMocks
@Autowired
@Qualifier("serviceClass")
private ServiceClass srv;

@Mock
@Autowired
@Qualifier("DaoA")
protected Dao dao;

@Mock
@Autowired
@Qualifier("DaoFactory")
protected DaoFactory daoFactory;

@Override
public void mockBehaivors() throws ResourceException, ResourceNotFoundException, ApiException {
    MockitoAnnotations.initMocks(this);

    when(daoFactory.getInstance(GroupBrand.A)).thenReturn(dao);

    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");
    } 

它的作品!!!!

答案 1 :(得分:0)

尝试在DAO上使用@MockBean(理想情况下@Mock也相同)并进行如下所述的存根。 在测试用例初始化方法上注释@Before并将子句逻辑移动到实际测试用例(我总是这样做)

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceTest extends MyServiceImpl {



    @Autowired
    private MyService myervice;

    @MockBean
    private MyDAO myDao;

    @Before
    public void setupMock()
    {
        MockitoAnnotations.initMocks(this);
    }
  

你可以尝试创建存根以便不调用DAO,如下面的代码片段所示   测试用例。在你的例子中,你已经在测试中完成了它   初始化块

     AddressDTO planContactaddressDTO = buildAddressDTO();
   //build this stub method buildAddressDTO() to return AddressDTO which your actual DAO will return
   when(myDao.saveAddress(addressBO)).thenReturn(addressDTO);