2015-02-11 94 views
1

我正嘗試通過Mockito使用PowerMock;因爲我喜歡API的whennew()和verifyprivate(),但當我嘗試在Junit中運行類TestRunner的測試套件時遇到了一些問題。當使用PowerMockRule使用PoweMock時ExpectedException測試失敗

對於使用默認的JUnit測試運行器,我創建了一個TestCase並添加了PowerMockRule作爲實例字段,其中@Rule註釋。而執行測試像這樣工作,的ExpectedException TestRule是不工作連用

示例代碼

@PowerMockIgnore ("*") 
@PrepareForTest (CustomizedSSHConnection.class) 
public class TestExpectedExceptionRule { 

    private Connection   connection; 
    private ConnectionInfo  connectionInfo; 
    @Rule 
    public PowerMockRule rule = new PowerMockRule(); 
    @Rule 
    public ExpectedException exception = ExpectedException.none(); 

    @Test 
    public void testExcepitonWithPowerMockRule() { 
     exception.expect (NullPointerException.class); 
     exception.expectMessage ("Image is null"); 
     throw new NullPointerException ("Image is null"); 
    } 
} 

當代替使用@rule PowerMockRule的,如果我使用@RunWith(PowerMockRunner.class)此測試用例會通過。

另外一個觀察是,如果我用@ClassRule註釋PowerMockRule,這會成功,但一些模擬方法會拋出異常。

+0

它以什麼方式不起作用?什麼是行爲?它沒有得到預期的例外,並且因爲預期異常而失敗了。 – 2015-02-11 16:57:30

+0

預期的輸出是驗證與消息一起拋出的異常並返回成功;但相反,它將拋出異常提升爲未捕獲的異常,並將測試報告爲錯誤。 – 2015-02-11 18:36:04

+0

約翰,我能夠解決這個問題,使用@Test註釋期望的屬性。但尋找一些使用ExpectedException TestRule來驗證異常的正確方法。 – 2015-02-11 18:41:51

回答

2

PowerMock創建了TestExpectedExceptionRule對象的深層克隆。正因爲如此,它正在運行一個新的ExpectedException規則的測試,但您要對原始規則調用exception.expect (NullPointerException.class)。因此,測試失敗,因爲ExpectedException規則的克隆不期望發生異常。

儘管如此,至少有兩種解決方案可以解決您的問題。

RuleChain

秩序與JUnit的RuleChain規則。這需要一些額外的醜陋代碼,但它的工作原理。

private ExpectedException exception = ExpectedException.none(); 
private PowerMockRule powerMockRule = new PowerMockRule(); 

@Rule 
public TestRule ruleChain = RuleChain.outerRule(new TestRule() { 
    @Override 
    public Statement apply(Statement base, Description description) { 
     return powerMockRule.apply(base, null, description); 
    } 
}).around(exception); 

魚缸

如果您使用的是Java 8則可以更換ExpectedException規則與Fishbowl庫。

@Test 
public void testExcepitonWithPowerMockRule() { 
    Throwable exception = exceptionThrownBy(
    () -> throw new NullPointerException ("Image is null")); 
    assertEquals(NullPointerException.class, exception.getClass()); 
    assertEquals("Image is null", exception.getMessage()); 
} 

沒有Java 8,你必須使用匿名類。

@Test 
public void fooTest() { 
    Throwable exception = exceptionThrownBy(new Statement() { 
    public void evaluate() throws Throwable { 
     throw new NullPointerException ("Image is null"); 
    } 
    }); 
    assertEquals(NullPointerException.class, exception.getClass()); 
    assertEquals("Image is null", exception.getMessage()); 
} 
+0

感謝精彩,詳細的答案Stefan,它使用Lambdas很有效... – 2015-08-15 18:42:38

-1

我能夠使用@Test註釋中的預期屬性修復此問題。但是這種方法的問題是我們無法斷言異常信息。現在對我來說很好。

@PowerMockIgnore ("*") 
@PrepareForTest (CustomizedSSHConnection.class) 
public class TestExpectedExceptionRule { 

    private Connection   connection; 
    private ConnectionInfo  connectionInfo; 
    @Rule 
    public PowerMockRule rule = new PowerMockRule(); 
    @Rule 
    public ExpectedException exception = ExpectedException.none(); 

    @Test(expected = NullPointerException.class) 
    public void testExcepitonWithPowerMockRule() { 
     throw new NullPointerException ("Image is null"); 
    } 
} 
相關問題