Mockito not able to mock non-final and visible class.

1,045 views
Skip to first unread message

Felipe Zampa

unread,
Jan 18, 2018, 5:04:36 PM1/18/18
to mockito
Hello all. 

I'm trying to mock a class named ObjectFactory, (created from xsd files with the command "xjc *.xsd") in my tests, without success. The exception stack says:

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class com.flyairnorth.integration.org.opentravel.ota._2003._05.ObjectFactory
Mockito can only mock visible & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl$1.withBefores(JUnit45AndHigherRunnerImpl.java:27)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:276)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
...

My test class:


@RunWith(MockitoJUnitRunner.class)

public class BookingServiceTest {


@Mock

private ObjectFactory objectFactory;


@Spy

@InjectMocks

private BookingValidator bookingValidator = new BookingValidator();


@InjectMocks

private BookingService service;

@Before

public void before() {

when(objectFactory.createOTAAirBookRS()).thenCallRealMethod();

when(objectFactory.createErrorsType()).thenCallRealMethod();

when(objectFactory.createErrorType()).thenCallRealMethod();

}


@Test

public void shouldContainErrorsForPassengerWithoutPassengerTypeCode() {

OTAAirBookRQ request = new OTAAirBookRQ();

AirTraveler traveler = new AirTraveler();

traveler.setPassengerTypeQuantity(new PassengerTypeQuantityType());

TravelerInfoType travelerInfoType = new TravelerInfoType();

travelerInfoType.getAirTraveler().add(traveler);

request.setTravelerInfo(travelerInfoType);


OTAAirBookRS bookingResponse = service.createBooking(request);

List<ErrorType> errors = bookingResponse.getErrors().getError();

assertThat(errors.isEmpty(), equalTo(false));

ErrorType error = errors.stream().filter(e -> e.getNodeList().contains("/PassengerTypeCode")).findFirst().orElse(null);

assertNotNull(error);

}

}


And finally, the class ObjectFactory is a huge amount of code that encapsulates some code like "return new AnotherObject()", but it has references to java.xml.bind classes (what I suspect might be the root cause). The code above is supressed due to it's size:


package com.flyairnorth.integration.org.opentravel.ota._2003._05;


import javax.xml.bind.JAXBElement;

import javax.xml.bind.annotation.XmlElementDecl;

import javax.xml.bind.annotation.XmlRegistry;

import javax.xml.namespace.QName;


import com.flyairnorth.integration.org.opentravel.ota._2003._05.AirReservationType.BookingReferenceID;

import com.flyairnorth.integration.org.opentravel.ota._2003._05.OTAAirBookRS.AirReservation;



@XmlRegistry

public class ObjectFactory {


    private final static QName _OntologyExtension_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "OntologyExtension");

    private final static QName _TPAExtensions_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "TPA_Extensions");

    private final static QName _ParagraphTypeImage_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "Image");

    private final static QName _ParagraphTypeURL_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "URL");

    private final static QName _ParagraphTypeText_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "Text");

    private final static QName _ParagraphTypeListItem_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "ListItem");

    private final static QName _CabinClassDetailTypeZone_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "Zone");

    private final static QName _CabinClassDetailTypeRowInfo_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "RowInfo");

    private final static QName _CabinClassDetailTypeAvailabilityList_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "AvailabilityList");

    private final static QName _CabinClassDetailTypeSeatInfo_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "SeatInfo");

    private final static QName _AccommodationCategory_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "AccommodationCategory");

    private final static QName _AccommodationService_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "AccommodationService");

    private final static QName _VehReservation_QNAME = new QName("http://www.opentravel.org/OTA/2003/05", "VehReservation");


    public ObjectFactory() {

    }


    public AcceptablePaymentCardsInfoType createAcceptablePaymentCardsInfoType() {

        return new AcceptablePaymentCardsInfoType();

    }


    @XmlElementDecl(namespace = "http://www.opentravel.org/OTA/2003/05", name = "AccommodationCategory")

    public JAXBElement<AccommodationCategoryType> createAccommodationCategory(AccommodationCategoryType value) {

        return new JAXBElement<AccommodationCategoryType>(_AccommodationCategory_QNAME, AccommodationCategoryType.class, null, value);

    }


...

}


My JVM is updated:

$ java -version
java version "1.8.0_161"
Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)

Is this error being caused due to the @XmlRegistry in ObjectFactory class?

Does someone has any tip to help?

Thank you.

Felipe.
Reply all
Reply to author
Forward
0 new messages