2017-08-09 92 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一樣!