Java 如何在不运行方法的情况下模拟方法调用和返回值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34308877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:31:22  来源:igfitidea点击:

How to mock method call and return value without running the method?

javajunitmockito

提问by Sorona

Consider the following method:

考虑以下方法:

public boolean isACertainValue() {
        if(context.getValueA() != null && context.getValueA().toBoolean() == true) {
        if(context.getType() != null && context.getType() == ContextType.certainType) {
            return true;
        }
    }
    return false;
}

I did not write this code, it is ugly as hell, it is totally overcomplicated but I have to work with it.

这段代码不是我写的,它丑得要命,它完全过于复杂,但我必须使用它。

Now I want to test a method that relies on a call to this method.

现在我想测试一个依赖于调用这个方法的方法。

I thought I could deal with this by:

我以为我可以通过以下方式处理这个问题:

Mockito.when(spy.isACertainValue()).thenReturn(true);because that's the case I want to test.

Mockito.when(spy.isACertainValue()).thenReturn(true);因为这就是我想要测试的情况。

But it doesn't work as it is still calling the method-body :/

但它不起作用,因为它仍在调用方法体:/

I get nullpointers or rather I get something along the lines of

我得到了空指针,或者更确切地说我得到了一些类似的东西

misusing.WrongTypeOfReturnValue; Boolean cannot be returned by getValueA(). getValueA() should return ValueA

misusing.WrongTypeOfReturnValue; getValueA() 不能返回布尔值。getValueA() 应该返回 ValueA

So I tried (as a workaround) to do:

所以我尝试(作为一种解决方法)这样做:

Mockito.when(contextMock.getValueA()).thenReturn(new ValueA());and Mockito.when(contextMock.getType()).thenReturn(ContextType.certainType);

Mockito.when(contextMock.getValueA()).thenReturn(new ValueA());Mockito.when(contextMock.getType()).thenReturn(ContextType.certainType);

but then I get a nullpointer that I cant seem to be able to debug.

但是后来我得到了一个我似乎无法调试的空指针。

So, how is it done right in this case?

那么,在这种情况下它是如何正确完成的呢?

采纳答案by Tunaki

When you are invoking

当你调用

Mockito.when(spy.isCertainValue()).thenReturn(true);

the method isCertainValue()is getting called here. This is how Java works: to evaluate the argument of Mockito.when, the result of spy.isCertainValue()must be evaluated so the method must be called.

该方法isCertainValue()在这里被调用。这就是 Java 的工作方式:要评估 的参数Mockito.whenspy.isCertainValue()必须评估的结果,因此必须调用该方法。

If you don't want that to happen, you can use the following construct:

如果您不希望发生这种情况,可以使用以下构造

Mockito.doReturn(true).when(spy).isCertainValue();

This will have the same mocking effect but the method won't be called with this.

这将具有相同的模拟效果,但不会用 this 调用该方法。

回答by Chris Sim

This code is correct:

这段代码是正确的:

Mockito.when(contextMock.getType()).thenReturn(ContextType.certainType);

But you are getting NullPointerException because you didn't define the Mocking value that should be defines, well I'm using Spring, in my context file when I define @Autowiredbean I define it this way:

但是你得到 NullPointerException 因为你没有定义应该定义的 Mocking 值,我正在使用 Spring,在我定义@Autowiredbean 的上下文文件中我这样定义它:

<bean id="contextMock" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.example.myspringproject.bean.ContextMock" />
</bean>