簡體   English   中英

使用PowerMock模擬鏈接方法調用

[英]Mocking chained methods calls using PowerMock

我有一個要通過公共靜態方法測試的類,該方法包含一些鏈接的方法調用。 假設在鏈接方法調用期間發生異常,如何有效地處理此異常並使它返回某些特定值?

以下是測試類的代碼示例。

@RunWith(PowerMockRunner.class)
@PrepareForTest({CodeWithPrivateMethod.class,CodeWithAnotherPrivateMethod.class,CodeWithYetAnotherPrivateMethod.class})
public class CodeWithPrivateMethodTest {

@Test
public void when_gambling_is_true_then_always_explode() throws Exception {


    CodeWithYetAnotherPrivateMethod codeWithYetAnotherPrivateMethod = PowerMockito.spy(new CodeWithYetAnotherPrivateMethod());
    PowerMockito.whenNew(CodeWithYetAnotherPrivateMethod.class).withAnyArguments().thenReturn(codeWithYetAnotherPrivateMethod);

    CodeWithAnotherPrivateMethod codeWithAnotherPrivateMethod = PowerMockito.spy(new CodeWithAnotherPrivateMethod());
    PowerMockito.whenNew(CodeWithAnotherPrivateMethod.class).withAnyArguments().thenReturn(codeWithAnotherPrivateMethod);

    PowerMockito.doReturn(true).when(codeWithYetAnotherPrivateMethod, "getGambling");

    //PowerMockito.doReturn(codeWithYetAnotherPrivateMethod).when(codeWithAnotherPrivateMethod, "getGambleValue");

    PowerMockito.spy(CodeWithPrivateMethod.class);
    CodeWithPrivateMethod.startGamble();

    }

}

以下是被測類的代碼示例

public class CodeWithPrivateMethod {

public static void startGamble() {

    Boolean gamble = CodeWithAnotherPrivateMethod.getGambleValue()
            .getGambling();
    if (gamble) {
        System.out.println("kaboom");
    }else{
        System.out.println("boom boom");
    }
    }
}

以下是從被測類調用的類的代碼示例

public class CodeWithAnotherPrivateMethod {

static CodeWithYetAnotherPrivateMethod codeWithYetAnotherPrivateMethod = new CodeWithYetAnotherPrivateMethod();


public static CodeWithYetAnotherPrivateMethod getGambleValue() {
    return codeWithYetAnotherPrivateMethod; //works fine
    return null; // fails
    }
}

以下是從被測類調用的另一個類的代碼示例

public class CodeWithYetAnotherPrivateMethod {

public Boolean getGambling() {
    return false;
    }
}

因此,假設我從CodeWithAnotherPrivateMethod類的getGambleValue()方法返回了空值,如何在我的測試類中有效地處理該空值?

這是使用Mockito指定預期異常的方法:

@Test(expected = NullPointerException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
    ...

在我發現這一點之前,我會做:

@Test
public void when_gambling_is_true_then_always_explode() throws Exception {
    // setup omitted
    try {
        CodeWithPrivateMethod.startGamble();
    } 
    catch(NullPointerException e) {
        // expected
        return;
    }
    fail("Expected NullPointerException");
}

編輯:測試多個這樣靜態調用彼此的類是一種嚴重的代碼味道。 單元測試應測試單個類,而內聯靜態調用應限於實用程序類。

另一個評論:您的示例類名稱非常混亂。 下次,請堅持使用Foo,Bar,Baz或Appple,梨,香蕉。

如果您沒有獲得NPE,那么我希望您的嘲笑/間諜活動會造成干擾。 如果您在不進行模擬/間諜的情況下調用受測代碼,則調用鏈為:

CodeWithPrivateMethod.startGamble();
->
CodeWithYetAnotherPrivateMethod value = CodeWithAnotherPrivateMethod.getGambleValue();
-> 
return null;
<-
value.getGambling();
<- throws NullPointerException

您到底想找出或實現什么?

編輯:這是它應如何與PowerMock一起使用

@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithAnotherPrivateMethod.class)
public class CodeWithPrivateMethodTest {

  @Mock
  private CodeWithYetAnotherPrivateMethod yetAnotherInstance;

  @Test
  public final void testStartGamble() {

    // SETUP
    mockStatic(CodeWithAnotherPrivateMethod.class);
    expect(CodeWithAnotherPrivateMethod.getGambleValue())
        .andReturn(yetAnotherInstance);
    Boolean gamblingValue = true;
    expect(yetAnotherInstance.getGambling()).andReturn(gamblingValue);
    replayAll();

    // CALL
    CodeWithPrivateMethod.startGamble();

    // VERIFY
    verifyAll();
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM