当前位置: 首页 > 知识库问答 >
问题:

使用PowerMockito和Mockito测试对其他工件方法的调用

鲁炳
2023-03-14

我确信这是一个很常见的问题,但我真的无法摆脱这个问题,我正在嘲弄私有方法,它内部调用另一个方法并返回一个集合。类有一个公共方法,它调用私有方法来获取集合对象。我使用PowerMock创建了一个私密方法的间谍。

public void method1(String s)
{
     Collection<Object> list = invokePrivate()
}

private Collection<Object> invokePrivate()
{
     Wrapper wrapperObj = Factory.getInstance.getWrapper();
     Collection<Object> list = wrapperObj.callWrapperMethod(); // This always calls into real method, instead of mocked version.
     return list;
}

测试类-:

因此,为了测试公共html" target="_blank">方法“method1”,我使用PowerMockito创建了一个spy来监视私有方法并返回一个演示列表。

MainClass obj = new MainClass();
MainClass spy = PowerMockito.spy(obj);
PowerMockito.when(spy, method(MainClass.class, "inokePrivate"))
                            .thenReturn(list); // demo list which exists as a test class member.

上面调用private method,然后尝试调用WrapperObj.CallWrapperMethod(),后者驻留在一个不同的工件中,并在其中中断,因为它没有找到某个实现。所以我尝试模拟WrapperObj.CallWrapperMethod。

WrapperClass wr = new WrapperClass();
WrapperClass spy1 = PowerMockito.spy(wr);
when(spy1.callWrapperMethod()).thenReturn(list) // demo list which exists as a test class member.

上面的模拟再次调用callWrapperMethod()的实际实现,并在其中中断。如何防止调用包装方法的实际实现?

对我有帮助的答案很少--:

mockito:如何模拟在另一个方法内部调用的方法

使用mockito测试私有方法

[更新]-:正如我所建议的那样-:

PowerMockito.doReturn(list).when(spy1).callWrapperMethod(); // This returns me demo list successfully.

但现在,当我从PowerMockito调用private方法时,控件进入invokePrivate方法,并再次尝试调用原始的callWrapperMethod而不是从spy版本返回list。

共有1个答案

孔建柏
2023-03-14

我建议不要这样做。您的私有方法不应使用静态方法检索单例工厂对象。

静态的东西打破“容易”的嘲讽;强迫你使用“权力”嘲讽;从而造成的问题多于解决的问题。

更改代码以使用依赖项注入。这样做:

class YourClass {
  private final Factory factory;

  public YourClass() {
     this(Factory.getInstance(); }

  YourClass(Factory theFactory) {
     this.factory = theFactory;
  ...

这将允许您在单元测试中使用第二个构造函数;为您的类提供一个(容易被模仿的)工厂对象。从而消除了对PowerMock的全部需求。

长话短说--当代码很难测试时;更改代码;而不是测试。作为一个副作用,您正在改进您的代码质量--因为您放松了对那个单例对象的硬依赖。

为了完整起见:我还建议避免“破坏”Demeter定律(http://en.wikipedia.org/wiki/Law ofdemeter):如果您的类需要包装器;那么它应该保存一个包装对象;如果它需要那个工厂;那么它应该包含一个工厂对象。但是你不应该持有一个对象...从那里检索另一个对象,在第二个对象上运行一些东西。正如你所看到的那样--这样做恰恰导致了你所面临的那种问题。

 类似资料:
  • 我有一个类需要进行单元测试: 我有一个测试用例: 当我运行测试用例时,没有使用ActiveMQConnectionFactory的模拟对象。相反,正在使用实际的实现,并且正在建立TCP连接: 我尝试了Powermockito和Mockito,但都失败了。如何模拟对象,如何成功运行测试用例? 我是单元测试新手,试图从各个社区获得帮助,但没有找到合适的答案。任何帮助都将不胜感激。谢谢

  • 所以我肯定有类似的东西在那里,但我已经搜索了一个小时,还没有找到确切的我要找的东西。假设我有一个这样的类: 我该如何制作这样的作品?

  • 实际上,它的测试如果eat方法对宠物有效,但我也需要检查feedPet方法对玩家也有效。 任何想法或建议都非常感谢。

  • 我是单元测试的新手,最近尝试了JUnit测试和Mockito。 我很困惑我该如何测试公共功能。

  • 您好,我对Junit和Mockito的单元测试相当陌生。我认为我对这些原则有一个相当合理的理解,但我似乎找不到任何解释来解释我特别想在网上测试什么。 我想测试一个方法,它调用其他几个方法(void和non-void),该方法还实例化了方法体中的对象。不幸的是,我不能分享代码,因为它不是我的,但这里有一个通用格式: 目前我只关心测试method_1,我不能直接测试,因为它是一个私有方法,所以我必须通