2

(はい、私は知っています。失敗を認めてPowerMockに頼らなければならないと考える人もいます)

こんにちは、

バージョン: 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");
    }
}

残念ながら、このテストは巨大なスタック トレースで失敗します。

java.lang.RuntimeException: java.lang.ExceptionInInitializerError
    at org.testng.internal.MethodInvocationHelper.invokeDataProvider(MethodInvocationHelper.java:143)
    at org.testng.internal.Parameters.handleParameters(Parameters.java:426)
    at org.testng.internal.Invoker.handleParameters(Invoker.java:1383)
    at org.testng.internal.Invoker.createParameters(Invoker.java:1075)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1180)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
    at org.testng.SuiteRunner.run(SuiteRunner.java:240)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1198)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1123)
    at org.testng.TestNG.run(TestNG.java:1031)
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:111)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.ExceptionInInitializerError
    at org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter.<init>(ConditionalStackTraceFilter.java:17)
    at org.mockito.exceptions.base.MockitoException.filterStackTrace(MockitoException.java:30)
    at org.mockito.exceptions.base.MockitoException.<init>(MockitoException.java:19)
    at org.mockito.exceptions.misusing.MockitoConfigurationException.<init>(MockitoConfigurationException.java:18)
    at org.mockito.internal.configuration.ClassPathLoader.loadImplementations(ClassPathLoader.java:145)
    at org.mockito.internal.configuration.ClassPathLoader.findPluginImplementation(ClassPathLoader.java:110)
    at org.mockito.internal.configuration.ClassPathLoader.findPlatformMockMaker(ClassPathLoader.java:106)
    at org.mockito.internal.configuration.ClassPathLoader.<clinit>(ClassPathLoader.java:59)
    at org.mockito.internal.util.MockUtil.<clinit>(MockUtil.java:21)
    at org.mockito.internal.configuration.injection.scanner.MockScanner.<init>(MockScanner.java:22)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.injectMocks(InjectingAnnotationEngine.java:96)
    at org.powermock.api.mockito.internal.configuration.PowerMockitoInjectingAnnotationEngine.process(PowerMockitoInjectingAnnotationEngine.java:38)
    at org.powermock.api.extension.listener.AnnotationEnabler.injectSpiesAndInjectToSetters(AnnotationEnabler.java:58)
    at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:2014)
    at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:744)
    at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:415)
    at org.powermock.modules.testng.internal.PowerMockTestNGMethodHandler.injectMocksUsingAnnotationEnabler(PowerMockTestNGMethodHandler.java:72)
    at org.powermock.modules.testng.internal.PowerMockTestNGMethodHandler.invoke(PowerMockTestNGMethodHandler.java:47)
    at com.github.fge.jsonschema.processing.syntax.SyntaxProcessorTest_$$_javassist_0.notSchemas(SyntaxProcessorTest_$$_javassist_0.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
    at org.testng.internal.MethodInvocationHelper.invokeDataProvider(MethodInvocationHelper.java:135)
    ... 26 more
Caused by: java.lang.NullPointerException
    at org.mockito.internal.exceptions.stacktrace.StackTraceFilter.<clinit>(StackTraceFilter.java:21)
    ... 56 more

このページを読んで、代わりにテストを拡張しようとPowerMockTestCaseしましたが、別のエラーで失敗しました:

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

では、そのようなテストをどのように記述しますか?

(編集:TestNG、mockito、およびpowermockのバージョンを@ user1951544が提案するバージョンにダウングレードしようとしました。それは私ではなく彼のために機能します...しかし、今回は両方のシナリオで2番目の短い例外が発生します)

4

2 に答える 2

2

これは PowerMock で実行できます。単体テストに @RunWith @PrepareForTest という 2 つの注釈を追加し、Mockito のスパイ/モック メソッドを PowerMockito のものに置き換える必要があります。

ここでいくつかの便利な例を見つけることができます: http://www.smartics.de/archives/1233

最も単純なテストは次のようになります。

@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 の場合、 http: //almirsadikovic.blogspot.fr/2011/07/testng-and-powermockito-powermock.htmlまたはCant mock static functionsの例のように、(@RunWith の代わりに) 適切な ObjectFactory を設定する必要があります。 powermock-easymock-testng を使用 (非 Maven プロジェクト)

于 2013-01-30T17:21:47.830 に答える
1

2番目の問題の回避策を見つけることができました。

ここで説明されているように、testng/powermock バージョンに何らかの問題があるようです: http://code.google.com/p/powermock/issues/detail?id=414

私のテストケースでは、powermock のバージョンを 1.4.11 に、testng を 6.4 に変更したところ、すべて正常に動作しました:)

トリッキーなもの...

于 2013-01-30T19:15:12.567 に答える