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

模拟旁路静态试验法

长孙深
2023-03-14

我需要使用mockito测试handleIn()方法。

但是,代码需要调用这个遗留代码util.getContextPDO,它是一个静态方法。

注意,在测试环境中,这个util.getContextPDO总是返回异常,我打算通过始终返回一个虚拟IPDO来绕过这个util.getContextPDO()。

public class MyClass {
  public IPDO getIPDO() 
  {
    return Util.getContextPDO(); // note that Util.getContextPDO() is a static, not mockable.
  }

  public String handleIn(Object input) throws Throwable 
  {
    String result = "";
    IPDO pdo = getIPDO();

    // some important business logic.

    return result;
  } 
}

最初,我认为这可以通过使用类“MyClass”的spy()来实现,这样我就可以模拟getIPDO()的返回值。下面是我使用spy()所做的初步工作

@Test
public void testHandleIn() throws Exception
{
    IPDO pdo = new PDODummy();


    MyClass handler = new MyClass ();
    MyClass handler2 = spy(handler);

    when(handler2.getIPDO()).thenReturn(pdo);
    PDOUtil.setPDO(pdo, LogicalFieldEnum.P_TX_CTGY, "test123");
    IPDO pdoNew = handler2.getIPDO();

    Assert.assertEquals("test123,(PDOUtil.getValueAsString(pdoNew, LogicalFieldEnum.P_TX_CTGY)));

}

然而,when(Handler2.GetIPdo()).ThenReturn(pdo);正在抛出我想要避免的异常(因为handler2.getipdo())似乎调用了真正的方法。

对如何测试这部分代码有什么想法吗?

共有3个答案

王豪
2023-03-14
when(handler2.getIPDO()).thenReturn(pdo);

将实际调用该方法,然后返回pdo

鉴于:

doReturn(pdo).when(handler2).getIPDO();

将返回pdo,而不调用getipdo()方法。

马绪
2023-03-14

在第三方API上消除静态调用的一个很好的技术是将静态调用隐藏在接口后面。

假设您制作了这个接口:

interface IPDOFacade {

    IPDO getContextPDO();
}

并且有一个默认实现,它只调用第三方API上的静态方法:

class IPDOFacadeImpl implements IPDOFacade {

    @Override
    public IPDO getContextPDO() {
        return Util.getContextPDO();
    }
}

那么只需将接口的依赖项注入MyClass中,并使用接口,而不是直接使用第三方API即可:

public class MyClass {

    private final IPDOFacade ipdoFacade;

    public MyClass(IPDOFacade ipdoFacade) {
        this.ipdoFacade = ipdoFacade;
    }

    public String handleIn(Object input) throws Throwable
    {
        String result = "";
        IPDO pdo = getIPDO();

        someImportantBusinessLogic(pdo);

        return result;
    }

    ...

}

在您的单元测试中,您可以轻松地模拟您自己的接口,以您喜欢的任何方式将其存根,并将其注入到被测试的单元中。

这个

  • 避免将私有方法包设为私有。
  • 通过避免部分嘲弄,使测试更具可读性。
  • 应用控制反转。
  • 将应用程序与特定的第三方库解耦。
鲜于渊
2023-03-14

将我的测试更改为:

@Test
public void testHandleIn() throws Exception
{
  IPDO pdo = new PDODummy();


  MyClass handler = new MyClass ();
  MyClass handler2 = spy(handler);

  doReturn(pdo ).when( handler2 ).getIPDO();
  PDOUtil.setPDO(pdo, LogicalFieldEnum.P_TX_CTGY, "test123");
  IPDO pdoNew = handler2.getIPDO();

  Assert.assertEquals("test123,(PDOUtil.getValueAsString(pdoNew, LogicalFieldEnum.P_TX_CTGY)));

}

解决后阅读有效的莫基托。

 类似资料:
  • 在Spring测试中,我知道我可以使用Mockito像模拟静态方法(通常是静态util方法:生成id,从Redis获取值): 但是每种测试方法都要这样做又丑又麻烦,有什么办法可以做到这一切(我可以有一个单一的嘲笑行为) 我在想可能是junit5扩展,或者Mockito扩展,这似乎是一个常见的问题,我想知道是否有人尝试了一些成功的东西。

  • 在安装到AEM 5.6.1实例之前,我正在使用maven构建和测试我的代码。我已经编写了单元测试,这些测试使用wcm的实现从aem模拟中获益。io和其他需要使用powermockito模拟静态方法的单元测试。 以下是我对aem上下文、sling Mock和powermock的maven依赖关系。 在我的课堂上,我正在为aem上下文设置规则,并准备一些用于模拟的静态类: 当我通过命令行运行mvn测试

  • 问题内容: 我的代码中有一个静态方法,希望以某种方式进行模拟。 我正在使用jmock。 我想可以做到这一点的一种方法是在静态方法周围设置“包装类”并模拟该方法,但是我希望有一个更好的解决方案。 我要用这种错误的方式? 反馈: 我将要有一个接口和一个类,该接口和类具有一个仅称为静态方法的方法。这将允许我通过仅模拟对此包装器类的调用来模拟逻辑。(即使谈论它我也觉得很脏:)) 问题答案: 我们不支持在j

  • 例如,我有以下课程: 我有一个类使用她的方法: 测试等级: 尝试运行测试时遇到的错误: 组织。莫基托。例外情况。基础MockitoException:对于TesteStatico,静态模拟已在当前线程中注册以创建新的模拟,必须取消注册现有的静态模拟注册 项目中LIB的版本: junit-jupiter 5.5.2 mockito-junit-jupiter 3.2.14 mockito-内联3.2

  • 我在一个类中有一个静态方法。方法不是最终的。我一直得到一个when()需要一个参数,该参数必须是'a method call on a mock‘错误。下面是我的代码。

  • 问题内容: 我对Java的座右铭是“仅仅因为Java具有静态块,并不意味着您应该使用它们。” 除了笑话,Java中还有许多使测试成为噩梦的技巧。我最讨厌的两个是匿名类和静态块。我们有很多使用静态块的遗留代码,这些是我们编写单元测试时最讨厌的点之一。我们的目标是能够以最小的代码更改为依赖于此静态初始化的类编写单元测试。 到目前为止,我对同事的建议是将静态块的主体移到私有的静态方法中并对其进行调用。然