Spock Mocking - 我的方法调用值没有被嘲笑

时间:2017-06-19 06:52:33

标签: java mocking spock

在我的帮助程序类的静态方法中调用getMarkup()时,它会抛出一个NPE。我所做的是模仿MarkupMaker和它的返回值,Markup的一个实例。最后,我想调用Markup实例的toString()。无论我做什么 - getMarkup()的召唤都在抛弃NPE。我找不到任何文档告诉我如何在spock中详细模拟方法调用值。

编辑:我添加了这个例子。 maker.getMarkup()的调用返回null,即使我在spock测试中嘲笑它。

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";
  }
}

3 个答案:

答案 0 :(得分:1)

删除模拟上的@Shared,因为模拟不支持。

答案 1 :(得分:1)

在您提供的示例中,MarkupHelper将始终返回null。你只是简单地调用maker.getMarkup()并且没有对它做任何事情。因此执行将继续return null

伦纳德的回答是正确的,因为你使用@Shared为什么你要在模拟对象上获得NPE,但是由于你的MarkupHelper实际上没有做什么,你的测试仍然不会得到满足你期待。

类似地,存在toString的MarkupObject模拟器无法正常工作,因为在您想要使用它时,它将不在模拟范围内,因此不会被使用。为了处理这个问题,你应该让你的MarkupHelper返回一个String,如:

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

如果您仍希望MarkupHelper返回MarkupObject,则在测试中您需要创建一个与实际属性具有相同属性的预期MarkupObject。

答案 2 :(得分:1)

我建议在每个测试方法中创建和模拟所有对象。在这种情况下,您将确保每个测试都是隔离的,共享数据不会影响您的结果。

关注您的示例,我将通过这两个测试覆盖getMarkupForIndex方法:

@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()
}