2012-11-28 30 views
3

我想知道如何指定在使用CDI進行測試時應該使用哪個模擬實現。CDI @Alternative - 每個測試用例選擇替代方案

我知道我可以用@Alternative標記一個模擬實現,但是我需要在beans.xml中定義它。我想有多個模擬(對於多個對象)。比方說,我有一個OrderService和一個EmailService。我正在寫一些驗收測試,我不希望EmailService發送電子郵件。然後,另一組測試是系統測試 - 我確實想發送電子郵件,但不應創建真實的訂單。

理想的解決方案是指定替代每個測試方法調用,像這樣:

@BeforeMethod 
public void before(){ 
    // in this test suite we're using mock email service 
    addAlternative(MockEmailService.class); 
} 
@Test 
public void testMyStuff(){ 
    issueAnOrder(); // and verify that it worked. no emails sent! 
} 

這可能嗎?

+0

我還沒有使用的Java EE CDI實現 - 我一直在使用,並且至今堅持春天依賴注入,但...一個常見的成語是使用依賴注入的應用,但要明確地設置測試類中的依賴關係 - 如果所有測試方法都使用相同的模擬方法,那麼在BeforeMethod中,或者如果不同的測試方法使用不同的模擬方法,則直接在測試方法的開始。 – GreyBeardedGeek

+0

我知道該怎麼做,我甚至已經粘貼了部分代碼......問題是如何注入其他內容 - 如何覆蓋「默認」bean。 – mabn

+0

再一次,我不知道Java EE CDI的細節,但大概你的測試沒有做CDI(或者你可以禁用它)。然後根據需要使用構造函數參數或訪問器方法來設置模擬屬性。 – GreyBeardedGeek

回答

1

我認爲你需要@ Alternative/@ Specialization和Arquillian的組合。 Arquillian爲集成測試提供了新的可能性,並允許您通過更改「beans.xml」爲每個測試指定不同的替代方案。具體細節請參考this問題。

0

Roland可能是最好的可接受的答案,另一種可能的方法是創建一個可移植的擴展,它將讀取您在測試或環境中設置的某些屬性以及ProcessAnnotatedType.veto()所需的版本。

Arquillian的另一個選擇是根本不捆綁所有的替代品,並有多個部署可供選擇。

1

CDI-Unit內置支持嘲諷http://jglue.org/cdi-unit/ 只需在測試類中指定模擬作爲生產者字段即可。

class Starship { 

    @Inject 
    Engine engine; //This will be mocked 

    void start() { 
    engine.start(); 
    } 
} 


@RunWith(CdiRunner.class) 
class TestStarship { 

    @Inject 
    Starship starship; 

    @Produces 
    @Mock // Mockito will create a mock for us. 
    Engine engine; 

    @Test 
    public void testStart() { 
    starship.start(); 

    // Verify that the mocks start method is called at least once. 
    Mockito.verify(engine, Mockito.atLeastOnce()).start(); 
    } 
} 
+0

最後,我們已經從spring 2.0遷移到了3.2(而不是CDI),並且我們使用springockito來對春豆進行模擬/間諜。 – mabn

相關問題