2017-06-19 96 views
0

在我的幫助器類的靜態方法中調用getMarkup()時,它會拋出一個NPE。我所做的是嘲弄MarkupMaker和它的返回值,這是Markup的一個實例。最終,我想調用Markup實例的toString()。無論我做什麼 - getMarkup()的電話都會拋出NPE。我找不到任何文檔告訴我如何在spock中詳細模擬方法調用值。Spock Mocking - 我的方法調用值沒有被模擬

編輯:我添加了這個例子。 maker.getMarkup()的呼叫甚至在我在嘲笑測試中嘲笑它。

Test.groovy

class TestExample extends Specification { 

    @Shared 
    MarkupMaker makerMock = Mock() 
    @Shared 
    MarkupObject markupMock = Mock() 

    def setup() { 
     markupMock.toString() >> "headline1" 
     makerMock.getMarkup() >> markupMock 
    } 

    @Unroll 
    def "Should return a Markupvalue #expectedvalue"(MarkupMaker helper, int tabElementIndex, String expectedValue) { 
     expect: 
     MarkupHelper.getMarkupForIndex(helper, tabElementIndex) == expectedValue 
     where: 
     helper | tabElementIndex | expectedValue 
     makerMock | 1    | "headline1" 

    } 

} 

Helper.java(執行的嘲笑對象的方法)

public class MarkupHelper { 

    public static MarkupObject getMarkupForIndex(MarkupMaker maker, int index){ 
    if(index == 1){ 
     maker.getMarkup(); 
    } 
    return null; 
    } 
} 

MarkupMaker.java(嘲笑對象之一)

public class MarkupMaker { 

    public MarkupObject getMarkup() { 
    return new MarkupObject(); 
    } 
} 

MarkupObject.java(最後嘲笑對象保存用於測試的值)

public class MarkupObject { 
    @Override 
    public String toString() { 
    return "headline1"; 
    } 
} 
+0

請張貼[MVCE(https://stackoverflow.com/help/mcve)。從這段代碼中不清楚有問題的代碼是如何被調用的。 –

+0

好吧WIP atm – xetra11

回答

1

在嘲笑卸下@Shared,因爲它不支持嘲笑。

1

在你的例子中,你提供了MarkupHelper將總是返回null。你只是簡單地打電話給maker.getMarkup()而不做任何事情。所以執行會繼續,並且return null

Leonard的答案是正確的,因爲你使用@Shared爲什麼你在模擬對象上得到NPE,但是由於你的MarkupHelper實際上並沒有達到你期望的效果,所以你的測試仍然不能滿足。

同樣的,你的stubing toString的MarkupObject模擬不會起作用,因爲當你想使用它的時候,它會在模擬之外,因此不會被使用。爲了處理這一點,你應該有你的MarkupHelper返回像一個字符串:

public static String getMarkupForIndex(MarkupMaker maker, int index){ 
    if(index == 1){ 
     return maker.getMarkup().toString(); 
    } 
    return null; 
} 

如果您仍然希望您的MarkupHelper返回一個MarkupObject,在測試你,而不是需要創建具有預期MarkupObject與您的實際相同的屬性。

1

我會建議創建並模擬每種測試方法中的所有對象。在這種情況下,您將確保每個測試都是隔離的,共享數據不會影響您的結果。

關注到您的例子,我將涵蓋getMarkupForIndex方法,通過這2個測試:

@Unroll 
def "getMarkupForIndex(..) returns null when the given index is #givenIndex"(){ 
    given: 
    def mockedMaker = Mock(MarkupObject) 

    when: 
    def actualResult = MarkupHelper.getMarkupForIndex(mockedMaker, givenIndex) 

    then: 
    actualResult == null 
    0 * _._ // no mock interaction at all 

    where: 
    givenIndex << [0, 2, 3] 
} 

def "getMarkupForIndex(..) returns a markup object when the given index is 1"(){ 
    given: 
    def expectedMarkupObject = new MarkupObject() 
    def mockedMaker = Mock(MarkupMaker) { 
     getMarkup() >> expectedMarkupObject 
    } 

    when: 
    def actualResult = MarkupHelper.getMarkupForIndex(mockedMaker, 1) 

    then: 
    actualResult.is(expectedMarkupObject) 
    1 * mockedMaker.getMarkup() 
} 
相關問題