0

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.

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi thanks. it was AutoConfigurationMockMvc which worked for me. However I also did some minor changes in the test controller above. Now only error i get is java.lang.AssertionError: Response content expected:<weather-history> but was:<<!DOCTYPE html> <html> it seems its returning the html page as in controller, but I want it to match with string "weather-history"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.