Java 如何使用PowerMock/Mockito和TestNG为最终类的(公共)方法编写一个_spy_? (是的,我知道,有些人认为必须诉诸PrimoMcCK承认失败)

Java 如何使用PowerMock/Mockito和TestNG为最终类的(公共)方法编写一个_spy_? (是的,我知道,有些人认为必须诉诸PrimoMcCK承认失败),java,testng,mockito,powermock,Java,Testng,Mockito,Powermock,你好, 版本:TestNG 6.8、Mockito 1.9.5和PowerMock 1.5 尽管在谷歌上搜索了很长一段时间,我还是找不到这样的例子 所讨论的类,SyntaxProcessor,有一个执行初步检查的process()方法,如果该检查通过,它将调用validate() 在这里,我故意使初步检查失败。我想检查validate()是否确实从未调用过 在@user1951544的帮助下,我想到了: @PrepareForTest(SyntaxProcessor.class) public

你好,

版本:TestNG 6.8、Mockito 1.9.5和PowerMock 1.5

尽管在谷歌上搜索了很长一段时间,我还是找不到这样的例子

所讨论的类,
SyntaxProcessor
,有一个执行初步检查的
process()
方法,如果该检查通过,它将调用
validate()

在这里,我故意使初步检查失败。我想检查
validate()
是否确实从未调用过

在@user1951544的帮助下,我想到了:

@PrepareForTest(SyntaxProcessor.class)
public final class SyntaxProcessorTest
{
    // ....

    @ObjectFactory
    public IObjectFactory getObjectFactory()
    {
        return new PowerMockObjectFactory();
    }

    // ....

    @DataProvider
    public Iterator<Object[]> notSchemas()
    {
        return SampleNodeProvider.getSamplesExcept(NodeType.OBJECT);
    }

    @Test(dataProvider = "notSchemas")
    public void syntaxProcessorYellsOnNonSchemas(final JsonNode node)
        throws ProcessingException
    {
        final ArgumentCaptor<ProcessingMessage> captor
            = ArgumentCaptor.forClass(ProcessingMessage.class);

        final ProcessingReport report = PowerMockito.mock(ProcessingReport.class);
        final JsonSchemaTree tree = new CanonicalSchemaTree(node);
        final ValidationData data = new ValidationData(tree);

        final Map<String, SyntaxChecker> map = Maps.newHashMap();
        final SyntaxProcessor processor = PowerMockito.spy(new SyntaxProcessor(map));

        processor.process(report, data);

        // No PowerMockito.verify()??
        // "any()" is from org.mockito.Matchers
        Mockito.verify(processor, never())
            .validate(any(SyntaxReport.class), any(JsonSchemaTree.class));

        final JsonNode msgNode = captor.getValue().asJson();
        assertEquals(msgNode.get("message").textValue(),
            "document is not a JSON Schema: not an object");
    }
}
那么,如何编写这样的测试呢


(编辑:还尝试将TestNG、mockito和powermock的版本降级到@user1951544建议的版本。这对他有效,对我无效……但这次我在两种情况下都得到了第二个更短的异常)

这可以通过powermock完成,您必须在单元测试中添加两个注释: @RunWith @准备工作 然后用PowerMockito的spy/mock方法替换Mockito的spy/mock方法

您可以在这里找到一些完整的示例:

最简单的测试可能如下所示:

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class MyClassTest {
    @Test
    public void test(){
        MyClass myClass = PowerMockito.spy(new MyClass());

        myClass.interfaceMethod(some arguments);
        Mockito.verify(myClass,Mockito.never()).otherMethod();              
    }

}

在TestNG的情况下,必须设置适当的ObjectFactory(而不是@RunWith),如或中的示例所示,我能够找到解决第二个问题的方法

testng/powermock版本似乎存在某种问题,如下所述:

在我的测试用例中,我将powermock版本更改为1.4.11,将testng更改为6.4,一切正常:)


棘手的东西…

嗯,TestNG没有@RunWith。。。看更多。我错过了你正在使用TestNG,在这种情况下,你必须将PowerMockObjectFactory设置为对象工厂,例如:或者在OK中,有“进步”,现在我得到了一个NPE,而不是Mockito对我大喊大叫它不能完成最终:pUh,我看到了那个页面,但没有建立关系。。。我会试试的呃,不,还是第二种情况下的错误。。。但这一次,使用ObjectFactory或extends。啊!不幸的是,我不能帮助它,这可能不是TestNG上下文中最好的建议,但也许你可以考虑切换到JUnit,而失去TestNG的@ DATAPLAGER?p否;)
java.lang.RuntimeException: Can't invoke method public void com.github.fge.jsonschema.processing.syntax.SyntaxProcessorTest.syntaxProcessorYellsOnNonSchemas(com.fasterxml.jackson.databind.JsonNode) throws com.github.fge.jsonschema.processing.ProcessingException, probably due to classloader mismatch
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class MyClassTest {
    @Test
    public void test(){
        MyClass myClass = PowerMockito.spy(new MyClass());

        myClass.interfaceMethod(some arguments);
        Mockito.verify(myClass,Mockito.never()).otherMethod();              
    }

}