2017-08-09 169 views
0

是新来的Junit Testing..I有一种情况,JUnit进行测试:未能测试的TransactionStatus

@Service 
public class MainWorkerClass { 

    @Autowired 
    @Qualifier("txnManager") 
    private HibernateTransactionManager txnManager; 

    public void task() { 
    ..... 
    TransactionStatus txnStatus = txnManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW)); 
    ..... 
    } 

} 

我的JUnit类的失败,getTransaction(),其中logger.isDebugEnabled()抛出NPE。 所以,我没有备用像下面,

public class JnuitTestTxnMgr implements PlatformTransactionManager{ 
    @Override 
    public void commit(TransactionStatus arg0) throws TransactionException {} 
    @Override 
    public TransactionStatus getTransaction(TransactionDefinition arg0) throws TransactionException { 
    return null; 
    } 
    @Override 
    public void rollback(TransactionStatus arg0) throws TransactionException {} 

} 

和我的JUnit类是喜欢,

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = {DBConfig.class}) 
public class MainWorkerClassTest { 
    @Mock 
    JnuitTestTxnMgr jnuitTransactionManagerOTP = new JnuitTestTxnMgr(); 
    @InjectMocks 
    MainWorkerClass worker = new MainWorkerClass(); 
    @Test 
    public void testTask() throws Exception{ 
    worker.task(); 
    } 

不过幸运的是,注入的模拟对象类型JnuitTestTxnMgr和类的被测试具有HibernateTransactionManager来未接受了一个。 有没有任何解决方法,我的替代解决方案或任何解决方案来测试我的原始类。

注意我不能改变我的罐子,现在用spring4 & hibernate4

+0

这就是为什么你想使用接口作为自动装配字段的类型而不是实现,所以你将能够轻松地嘲笑它们。 –

+0

谢谢,是通过自动装配接口,它的工作正常。但是这种情况下还有其他方法吗?因为我现在不想在服务类中进行修改。 – RajeysGS

回答

0

1.使用PowerMockRunner代替SpringRunner。 和在类

2的顶部使用@PrepareForTest({MainWorkerClass.class})@模拟
HibernateTransactionManager的txnManager。不要创建新的对象。

3.使用 DefaultTransactionDefinition mockobj = PowerMockito.mock(DefaultTransactionDefinition.class); PowerMockito.whenNew(DefaultTransactionDefinition.class).withArguments(Mockito.any())。然后返回(mockobj); TransactionStatus mockstat = Mockito.mock(TransactionStatus.class);

4.将@InjectMocks放在顶部,然后对其他对象使用@Mock。

5.Mockito.when(txnManager.getTransaction(mockobj))。thenReturn(mockstat);

使用这一切在你的junit.It应该运行。

+0

尝试所有无论你告诉,闻听异常正如我刚才所说, 显示java.lang.NullPointerException后:空 \t在org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:340) – RajeysGS

+0

春天是足够复杂通过它自己。从这个意义上说:春天的人们有充分的理由搭起自己的跑步者。该跑步者旨在通过Spring进行单元测试。您使用PowerMock的建议反而进入了完全错误的方向! – GhostCat

0

事情是:

@Mock 
JnuitTestTxnMgr jnuitTransactionManagerOTP; // = new JnuitTestTxnMgr(); 

@InjectMocks 
MainWorkerClass worker; // = new MainWorkerClass(); 

只有工作:

  • 当您使用时使用@RunWith(MockitoJUnitRunner.class)或
  • 另一个你打电话MockitoAnnotations.initMocks(this)

(见官方documentation

换句话说:你的问题是,你使用的是Spring亚军,这不初始化模拟对象。

除此之外:正确使用@Mock注释意味着你做而不是需要为变量赋值。与此相反的。你或者模拟一个对象,或者你给它分配一些东西! @InjectMocks一样!