PowerMock 的 expectNew() 没有按预期模拟构造函数

Posted

技术标签:

【中文标题】PowerMock 的 expectNew() 没有按预期模拟构造函数【英文标题】:PowerMock's expectNew() isn't mocking a constructor as expected 【发布时间】:2012-09-03 20:13:58 【问题描述】:

我正在尝试了解各种模拟库的来龙去脉,PowerMock(特别是 EasyMock 扩展)是列表中的下一个。我试图模拟一个构造函数,当我尝试复制它们时,提供的示例没有相同的响应。据我所知,它从不模拟构造函数,只是像正常一样继续进行。

这是测试类:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Writer.class)
public class FaultInjectionSituationTest 

    @Test
    public void testActionFail() throws Exception 
        FaultInjectionSituation fis = new FaultInjectionSituation();
        PowerMock.expectNew(Writer.class, "test")
           .andThrow(new IOException("thrown from mock"));
        PowerMock.replay(Writer.class);
        System.out.println(fis.action());
        PowerMock.verify(Writer.class);
    


我尝试用 EasyMock.isA(String.class) 替换“测试”,但结果相同。

这是FaultInjectionSituation:

public class FaultInjectionSituation 

    public String action()
        Writer w;
        try 
            w = new Writer("test");
         catch (IOException e) 
            System.out.println("thrown: " + e.getMessage());
            return e.getLocalizedMessage();
        
        return "returned without throw";
    

“Writer”只不过是一个类的外壳:

public class Writer 
    public Writer(String s) throws IOException 
    

    public Writer() throws IOException
    

测试运行时,打印出“returned without throw”,表示从未抛出异常。

【问题讨论】:

【参考方案1】:

您还需要准备调用构造函数的类,以便 PowerMock 知道期待模拟构造函数调用。尝试使用以下内容更新您的代码:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Writer.class, FaultInjectionSituation.class)
public class FaultInjectionSituationTest  
 // as before

【讨论】:

谢谢,我没有意识到调用构造函数的对象也需要包含在内。 我遇到了同样的问题......正是我所缺少的 :) 非常感谢,我挣扎了好久才找到这个答案。【参考方案2】:

你需要先创建一个模拟对象:

Writer mockWriter = PowerMock.createMock(Writer.class)
PowerMock.expectNew(Writer.class, "test").andReturn(mockWriter)

【讨论】:

我不是在尝试创建模拟对象,而是在尝试拦截构造函数并在其位置抛出异常。 this page 的“更多功能”部分是我的目标。 对不起,我明白你在做什么。我刚刚在 JUnit 4 上尝试了您的代码,它打印出“从模拟中抛出”(您所期望的)。您是否有机会使用 TestNG?我对 TestNG 不熟悉,但是当我使用 TestNG 运行它时,我得到了“没有抛出就返回” 我正在使用 Junit4。我想不出任何会导致它不起作用的东西。 我认为您的代码没有任何问题(因为我能够获得所需的输出)。你是如何运行 JUnit 的?从 IDE 或命令行? 我都试过了。我将它交给同事在他们的机器上运行,也许这将有助于阐明问题。

以上是关于PowerMock 的 expectNew() 没有按预期模拟构造函数的主要内容,如果未能解决你的问题,请参考以下文章

PowerMock学习之Mock Argument Matcher的使用

单元测试-PowerMock

PowerMock框架讲解及使用

powermock mock静态方法为啥会执行

PowerMock

powermock, 强力模拟