JMockit ไม่ตรงกับความคาดหวังที่บันทึกไว้

ฉันกำลังพยายามเยาะเย้ยวิธี SAXParser.parse(...) โดยใช้ JMockit

ฉันสามารถตั้งค่าความคาดหวังสำหรับลายเซ็นเมธอด parse (InputStream, DefaultHandler) ได้สำเร็จ แต่เมื่อฉันพยายามจำลองลายเซ็น parse (InputSource, DefaultHandler) JMockit จะไม่เห็นการร้องขอและส่งข้อยกเว้น MissingInvocation

ตัวอย่างต่อไปนี้แสดงกรณีทดสอบสองกรณี กรณีหนึ่งล้อเลียนรสชาติของ InputSource และอีกกรณีหนึ่งล้อเลียนรสชาติของ InputStream:

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());
    }
}

การรัน testcase ส่งผลให้:

    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: $Subclass_SAXParser_param0@490d6c15
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


person eakst7    schedule 08.06.2017    source แหล่งที่มา


คำตอบ (1)


TL;DR

ใช้คำอธิบายประกอบ @Capturing แทน @Mocked ในการทดสอบ InputSource

คำอธิบาย

ปัญหาของคุณคือวิธีการ SAXParser.parse(InputSource, DefaultHandler) ถูกแทนที่โดย SAXParserImpl ขณะที่คุณกำลังใช้คำอธิบายประกอบ @Mocked คุณกำลังเยาะเย้ยเฉพาะวิธีการจากคลาส SAXParser

SAXParserFactory.newInstance().newSAXParser() ส่งคืน SAXParserImpl ดังนั้นสำหรับเมธอด InputStream เนื่องจากไม่มีการแทนที่ จึงไปที่เมธอด SAXParser.parse(InputStream, DefaultHandler) ที่ถูกเยาะเย้ย

แต่สำหรับเมธอด InputSource เนื่องจากมีการแทนที่ มันจะไปที่เมธอดที่ไม่ได้จำลอง และด้วยเหตุนี้การร้องขอจึงขาดหายไป

หากคุณต้องใช้คำอธิบายประกอบ Capturing ที่จำลองอินเทอร์เฟซ/คลาสและคลาสย่อย/การใช้งานย่อยทั้งหมด คุณจะไม่มีข้อยกเว้นการเรียกใช้ที่ขาดหายไป

person Alfergon    schedule 09.06.2017
comment
อย่างแท้จริง. ยกเว้นว่าจนถึง JMockit 1.32 คลาส JRE ภายในจำนวนมากจากแพ็คเกจที่ไม่ได้มาตรฐาน (เช่น com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl) จะถูกแยกออกจาก @Capturing เนื่องจากปัญหาความคงทนในอดีต อย่างไรก็ตาม ใน JMockit 1.33 com.sun.org จะได้รับอนุญาต สิ่งนี้กล่าวว่า IMO การเยาะเย้ยตัวแยกวิเคราะห์ XML นั้นไม่จำเป็นและหลีกเลี่ยงได้ดีที่สุด - person Rogério; 10.06.2017
comment
ฉันใช้ 1.8 เลยไม่ได้สังเกตว่า :P - person Alfergon; 12.06.2017