I am totally new to Mockito and have already spent couple of days to write my web app in spring boot. The application runs perfectly fine but I want to learn mockito and want to test some of my class including controller, however I find this testing part so frustrating that I am almost on the verge of skipping this testing part. So I will explain the problem
Controller.java
@GetMapping("/checkWeather")
public String checkWeather(@RequestParam(name="city", required=true, defaultValue="Oops! you typed wrong url!")
String city, Map<String,Object> map, Model model)
throws IOException,HttpClientErrorException.NotFound {
try{
Weather result = getWeatherService.getNewWeatherObject(city);
map.put("weatherList",crudService.getAllWeatherList());
}catch (HttpClientErrorException e){
LOGGER.info("Typed City cannot be found, please type name correctly! Aborting program..");
return "notfound";
}
return "weather-history";
}
I want to test this controller which depends on one service which is:
GetWeatherService.java
@Service
public class GetWeatherService {
@Autowired
private ReadJsonObjectService readJsonObjectService;
public Weather getNewWeatherObject(String city) throws IOException {
String appid = "47c473417a4db382820a8d058f2db194";
String weatherUrl = "http://api.openweathermap.org/data/2.5/weather?q="+city+"&APPID="+appid+"&units=metric";
RestTemplate restTemplate = new RestTemplate();
String restTemplateQuery = restTemplate.getForObject(weatherUrl,String.class);
Weather weather = readJsonObjectService.setWeatherModel(restTemplateQuery);
return weather;
}
}
Now to test my controller i have written this test:
WeatherRestControllerTest.java
@AutoConfigureMockMvc
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class WeatherRestControllerTest extends AbstractTestNGSpringContextTests {
private Weather weather;
@Autowired
private MockMvc mockMVC;
@InjectMocks
private WeatherRestController weatherRestController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testCheckWeather() throws Exception {
GetWeatherService getWeatherService = Mockito.mock(GetWeatherService.class);
Mockito.when(getWeatherService.getNewWeatherObject("Munich")).thenReturn(new Weather());
mockMVC.perform(MockMvcRequestBuilders.get("/checkWeather?city=Munich")).
andExpect(MockMvcResultMatchers.status().isOk()).
andExpect(MockMvcResultMatchers.content().string("weather-history"));
}
}
But in the end on running the test I get this exception:
java.lang.NullPointerException
at com.weatherapi.test.weather_api.rest.WeatherRestControllerTest.getWeatherRest(WeatherRestControllerTest.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
I get NullPointerException and I have no idea what is going wrong. Why its throwing null. I am trying from morning to understand syntax but I am getting nothing. I spent couple of time researching and changing syntax but getting same error. Why it is so complicated and I still don't understand what is the purpose of doing all this.
EDIT:
I now have new implementation for WeatherRestcontrollerTest.java above. This I did as per the inputs in comments.
Ensure that the mockMvc gets injected properly.
Add @AutoConfigureMockMvc
to your test so that your test class declaration looks like:
@AutoConfigureMockMvc
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class WeatherRestControllerTest extends AbstractTestNGSpringContextTests
Also ensure that the mockMvc is @Autowired
@Autowired
private MockMvc mockMVC;
This way the mockMvc gets injected.
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.