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.