简体   繁体   中英

Test service with mockito

I'm new with Spring and Mockito testing. I couldn't find answer to my problem on Stack Overflow.

I have the following classes:

@Component
@Chronolog(logLevel = ChronologLevel.DEBUG)
public class CityService {

    private static final Logger LOGGER = LoggerFactory.getLogger(CityService.class);

    @Autowired
    private GeoClient geoClient;

    @Autowired
    private EOClient eoClient;

    /**
     *
     * @param rrCode
     * @return
     */
    public City getCityFromCode(String rrCode) {

        City city = new City();
        LinkedHashMap geoResponse = geoClient.getCityInfoByRRCode(rrCode);
        city.setRrCode(rrCode);
        LinkedHashMap result = (LinkedHashMap) geoResponse.get("City");
        if(result != null){
            city.setLabel((String) result.get("Name"));
        }else{
            city.setLabel("");
        }

        return city;
    }

    /**
     *
     * @param maxVia
     * @return
     */
    public List<OrigineDestination> getODFromMaxVia(String maxVia) {

        List<OrigineDestination> originesDestinations = new ArrayList<OrigineDestination>();
        OrigineDestination origineDestination;
        Trips odResponse = eoClient.getCityInfoByMAxVia(maxVia);

        for (Trip trip : odResponse.getTrip()) {
            origineDestination = new OrigineDestination();
            origineDestination.setOriginCity(trip.getOriginCity());
            origineDestination.setOriginStation(trip.getOriginStation());
            origineDestination.setDestinationCity(trip.getDestinationCity());
            origineDestination.setDestinationStation(trip.getDestinationStation());
            originesDestinations.add(origineDestination);
        }

        return originesDestinations;
    }

    /**
     *
     * @return
     */
    public Set<City> getOrigins() {
        List<OrigineDestination> retourOriginesDestination = getODFromMaxVia("1");
        Set<City> origins = new HashSet<>();
        Set<String> orrCodes = new HashSet<>();
        for (OrigineDestination origineDestination : retourOriginesDestination) {
            if (!orrCodes.contains(origineDestination.getOriginCity())) {
                orrCodes.add(origineDestination.getOriginCity());
                City city = new City();
                city.setRrCode(origineDestination.getOriginCity());
                city.setLabel(getCityFromCode(city.getRrCode()).getLabel());
                if(!city.getLabel().isEmpty()){
                    origins.add(city);
                }
            }
        }
        return origins;
    }

    /**
     *
     * @param origin
     * @return
     */
    public Set<City> getDestinations(String origin) {
        List<OrigineDestination> retourOriginesDestination = getODFromMaxVia("1");
        Set<City> matchedOrigins = new HashSet<>();
        Set<String> drrCodes = new HashSet<>();
        for (OrigineDestination origineDestination : retourOriginesDestination) {
            if (origin == null ||
                    (origin != null && origin.toUpperCase().equals(origineDestination.getOriginCity()))) {
                if (!drrCodes.contains(origineDestination.getDestinationCity())) {
                    drrCodes.add(origineDestination.getDestinationCity());
                    City city = new City();
                    city.setRrCode(origineDestination.getDestinationCity());
                    city.setLabel(getCityFromCode(city.getRrCode()).getLabel());
                    if(!city.getLabel().isEmpty()){
                        matchedOrigins.add(city);
                    }
                }
            }
        }
        return matchedOrigins;
    }
}

And my testing class looks like :

@RunWith(MockitoJUnitRunner.class)
public class CityServiceTest {

    @InjectMocks
    private CityService cityService;

    @Mock
    GeoClient geoClient;

    @Mock
    EOClient eoClient;

    @Test
    public void testGetOriginsCasOK() {
        cityService.getOrigins();
    }

    @Test
    public void testGetDestinationsCasOK() {
        cityService.getDestinations("FRPAR");
    }

    @Test
    public void testGetDestinationsCasKO() {
        cityService.getDestinations("FRET");
    }
}

My problem is that service is null i don't want to mock it. I tried several annotations, but didn't find which one to use.

What have i done wrong?

java.lang.NullPointerException
    at com.xxxx.matrixar.services.CityService.getODFromMaxVia(CityService.java:89)
    at com.xxxx.matrixar.services.CityService.getDestinations(CityService.java:129)
    at com.xxxx.matrixar.services.CityServiceTest.testGetDestinationsCasKO(CityServiceTest.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)

You need to specify what the mock object should return when they are actually called.

For example, in CityService.getODFromMaxVia() you call geoClient.getCityInfoByRRCode() and then use the result returned by this call.

A mock will always return null unless you specify something else:

when( geoClient.getCityInfoByRRCode( "FRPAR" ) ).thenReturn( ... );

This allows you to bypass the complex code in the mocked objects, and just return something that you'd expect in this case.

Remember: You're testing your service here, not the geo client. There are tests for the geo client elsewhere, so there is no point to make sure it does the right thing when being used in the service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM