2017-06-08 36 views
2

JMockitを使用してSAXParser.parse(...)メソッドをモックしようとしています。JMockitが記録された期待値と一致しません

パース(InputStream、DefaultHandler)メソッドのシグネチャの期待値を正しく設定できましたが、パース(InputSource、DefaultHandler)シグネチャをモックしようとすると、JMockitは呼び出しを見ず、MissingInvocation例外をスローします。でテストケースの結果を実行

public class SAXTest { 

    @Test(expected=RuntimeException.class) 
    public void testParseInputSource(@Mocked final SAXParser saxParser) throws Exception { 
     new Expectations() {{ 
      saxParser.parse((InputSource) any, (DefaultHandler) any); result = new RuntimeException("Fail now"); 
     }}; 

     SAXParser p = SAXParserFactory.newInstance().newSAXParser(); 
     InputSource isource = new InputSource(new StringReader("<test/>")); 
     p.parse(isource, new DefaultHandler());  
    } 

    @Test(expected=RuntimeException.class) 
    public void testParseInputStream(@Mocked final SAXParser saxParser) throws Exception { 
     new Expectations() {{ 
      saxParser.parse((InputStream) any, (DefaultHandler) any); result = new RuntimeException("Fail now"); 
     }}; 

     SAXParser p = SAXParserFactory.newInstance().newSAXParser(); 
     InputStream istream = new ByteArrayInputStream("</test>".getBytes()); 
     p.parse(istream, new DefaultHandler()); 
    } 
} 

次の例では、2つのテストケース、1 InputSourceの風味をからかっと1のInputStreamの風味をあざけるを示し

JUnit version 4.12 
E. 
Time: 0.069 
There was 1 failure: 
1) testParseInputSource(SAXTest) 
java.lang.Exception: Unexpected exception, expected<java.lang.RuntimeException> but was<mockit.internal.MissingInvocation> 
     at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28) 
... 
Caused by: Missing 1 invocation to: 
javax.xml.parsers.SAXParser#parse(any org.xml.sax.InputSource, any org.xml.sax.helpers.DefaultHandler) 
    on mock instance: [email protected] 
Caused by: Missing invocations 
     at javax.xml.parsers.SAXParser.parse(SAXParser.java) 
     at SAXTest$1.<init>(SAXTest.java:20) 
     at SAXTest.testParseInputSource(SAXTest.java:19) 

FAILURES!!! 
Tests run: 2, Failures: 1 

あなたは、見ることができるようにInputSourceのバージョンは失敗しますが、InputStreamのバージョンは正常に動作します。

私はJUnitの4.12を使用していますとJMockit 1.32

答えて

2

TL; DR

使用@Capturing annnotation代わりにInputSource試験に@Mocked 1。

説明

あなたの問題はSAXParser.parse(InputSource, DefaultHandler)方法がSAXParserImplによって上書きされていることです。 @Mockedアノテーションを使用している場合は、SAXParserクラスのメソッドのみをマックしています。何のオーバーライドがないので、それは嘲笑SAXParser.parse(InputStream, DefaultHandler)方法になり、InputStreamメソッドのよう

SAXParserFactory.newInstance().newSAXParser()は、SAXParserImplを返します。

しかし、InputSourceメソッドの場合、オーバーライドがあるので、それはnot mockedメソッドになり、そのため呼び出しが失われます。

Capturing注釈を使用すると、インターフェイス/クラスとそのすべてのサブクラス/サブ実装が非表示になりますが、欠落している呼び出し例外は発生しません。

+1

実際。 JMockit 1.32までを除いて、非標準パッケージからの多くの内部JREクラス( 'com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl'など)は、過去の堅牢性の問題のために' @ Capturing'から除外されています。しかし、JMockit 1.33では、 'com.sun.org'が許可されます。これは、IMOがXMLパーサーを嘲笑することは不要であり、避けることが最善であると述べました。 –

+0

私は1.8を使用しているので気付かなかった:P – Alfergon

関連する問題