java 如何在 spock 测试中模拟私有方法的返回值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35510073/
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-11-03 00:12:17  来源:igfitidea点击:

How to mock a return value of a private method in spock test

javaunit-testinggroovyspock

提问by photosynthesis

I want to test a public method in which it calls another private method, I used the following reflection way to get the private method and tried to mock the return value of it, but it didn't work as the test stops at where the private call is. Any suggestions?

我想测试一个调用另一个私有方法的公共方法,我使用以下反射方式来获取私有方法并尝试模拟它的返回值,但它不起作用,因为测试在私有方法停止电话是。有什么建议?

Method testMethod = handler.getClass().getDeclaredMethod("test", String.class)
testMethod.setAccessible(true)
testMethod.invoke(handler, "test string") >> true

The testMethod looks like the following:

testMethod 如下所示:

private boolean test(String str) {
    return true;
}

回答by Jérémie B

Spock mock classes by using cglib proxies. Such proxy can't mock final classes or private methods (as private method are implicitly final). If your code under test is written in Groovy (like a script, or a grails application), then you can use Spock GroovyMockor patch the metaclass :

Spock 模拟类使用 cglib 代理。这种代理不能模拟 final 类或私有方法(因为私有方法是隐式最终的)。如果您的测试代码是用 Groovy 编写的(如脚本或 grails 应用程序),那么您可以使用 SpockGroovyMock或修补元类:

setup:
  HandlerClass.metaClass.test = { true }

given: "a handler"
  def handler = new HandlerClass()

when: "i call test" 
  def r = handler.test()

then:
  r == true

However, you should probably focus more on the testability of your code. Having to mock classes is generally not a good sign about the maintainability and testability of the code...

但是,您可能应该更多地关注代码的可测试性。必须模拟类通常不是代码的可维护性和可测试性的好兆头......

回答by user2004685

You can't mock private methods using Mockito. But if there is an explicit need then you can try looking at PowerMock.

您不能使用 Mockito 模拟私有方法。但是如果有明确的需求,那么您可以尝试查看 PowerMock。

It is not expected to write the tests for private methods as they get covered when you write the tests for public methods.

不应为私有方法编写测试,因为在为公共方法编写测试时会覆盖这些测试。

If any of your mocks are being called in the private method then you can verify the calls by doing something like this:

如果在私有方法中调用了任何模拟,则可以通过执行以下操作来验证调用:

Mockito.verify(myMock, Mockito.times(1)).myMethod(myParams,...,...);