簡體   English   中英

使用mockito操縱參數的存根方法

[英]stubbing methods that manipulates parameters with mockito

我有以下情況:

class Worker {  
  public Integer somework() {  
      Integer k=0;  
      Helper h= new Helper();  
      h.change(k);  
      return k;  
    }
}

class Helper {
  public void change(Integer k) {
    //k = Some calcs
  }
}

我正在為Worker制作unitests,顯然我想要模仿Helper類,這樣他的change方法總是將1放入k

我的實際情況比較復雜,但這段代碼代表了問題。 感謝幫助。

我有一個定義如下的方法:

class Template{
   public void process(Object rootMap, StringWriter out){
 .......   
  }
 }

我將向您展示如何更改/修改“out”(StringWriter)引用。

private final Template mocktTemplate = mock(Template.class);
doAnswer(new Answer<StringWriter>() {

            public StringWriter answer(InvocationOnMock invocation)
                    throws Throwable {
                Object[] args = invocation.getArguments();
                if (args[1] instanceof StringWriter) {
                    StringWriter stringWriter = (StringWriter) args[1];
                    stringWriter.write("Email message");
                }
                return null;
            }
        }).when(this.mocktTemplate).process(anyObject(),any(StringWriter.class));

現在,當您確實進行實際調用時:

msgBodyTemplate.process(model, msgBodyWriter);

msgBodyWriter中Stringbuffer ref的值為“Email message”; 不論它早期的價值。

我認為doAnswer是處理void方法的最佳方法,其中方法操縱給定的參數。

doAnswer(new Answer() {
  public Object answer(InvocationOnMock invocation) {
      Object[] args = invocation.getArguments();
      Mock mock = invocation.getMock();
      return null;
  }})
.when(mock).someMethod();

基本上,在獲得參數后,您可以進行任何您想要的修改。 有一篇博客文章解釋了一下。

至於@JB Nizet的觀點,是的,重構可測試性是件好事。 通常,重構以使代碼更易於測試會導致代碼更好地用於其他原因 - 分離關注點等等。 這並不總是可行的。 假設它不是你的代碼,或者你有其他要求讓它不管它(因為很多其他類依賴於它的方式)或者其他什么。

如果我明白你需要做什么,我想你可以用間諜來做:

Worker workerUnderTest = new Worker();
Worker spiedWorkerUT = spy(workerUnderTest);
Helper mockHelper = mock(Helper.class);
when(spiedWorkerUT.createHelper()).thenReturn(mockHelper);
Integer actual = spiedWorkerUT.someWork();
verify(mockHelper).change(0);

然后使用spiedWorkerUT而不是workerUnderTest來運行測試。

並不總是可以避免實例化你想要模擬的東西。 為此,有PowerMock

Helper mockHelper = mock(Helper.class);
whenNew(Helper.class).withNoArguments().thenReturn(mockHelper);

我會更改方法簽名,並將Helper實例作為參數。 調用者將創建幫助程序並將其傳遞給somework方法。 測試將通過模擬助手。

如果這是不可能的,至少調用一個受保護的工廠方法來創建幫助器,並在測試somework方法時模擬這個工廠方法,以使它返回一個模擬助手:

class Worker {  
    public Integer somework(){  
        Integer k=0;  
        Helper h= createHelper();  
        h.change(k);  
        return k;  
    }

    // this method may be mocked when testing somework, to return a mock helper.
    protected Helper createHelper() {
        return new Helper();
    }
}

暫無
暫無

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

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