在我的帮助程序类的静态方法中调用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";
}
}
答案 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()
}