1
votes

I have a test class that @Autowireds two different classes in. One of them is @Service and the other is @RestController.

When I use the @Service one, it works fine.

When I use the @RestController one, it throws a NullPointerException.

Is there some reason why it can't wire up the Controller? I figured maybe it has something with creating the web context but I also tried adding the SpringBootTest with a webEnvironment pointing at MOCK (and others) to see if that would get it to kick in.

I also kicked around the MockMvc stuff but I am not exactly sure how that's supposed to work.

Is there some way to easily call one of these controllers to do a full integration test case?

@Autowired
private ThingService tservice;

@Autowired
private ThingController tconn;

@Test
public void testRunThing() {
    Thing t = new Thing(1, "Test");
    tservice.configureThing(t);
    Thing t2 = new Thing(1, "Second thing");
    tconn.getThing(t2);

    t3 = tservice.findThing(1);
    assertEqual(t3.getValue(), "Second thing");
}

The tservice function does a little bit including ultimately persisting to a DB (in this case H2 which it, in turn has autowired in through a repository).

The tconn function handles an update as if it was sent to the rest endpoint (in this case, it would update the "thing" with ID of 1 to the new string value)

the null pointer shows up on the tconn.getThing() call.

1
Can you please add the test class to the question?Boris
@Boris I added a bit of a cut down exampleMichaelB
Ok, and what are the annotations at the class level?Boris

1 Answers

1
votes

Simple example of MockMvc usage: Test class

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class LoginControllerTest {

    @Autowired
    private MockMvc mockMvc;

Simple test

        @Test
        public void loginOk() throws Exception {
            this.mockMvc.perform(post("/login").param("username", "name")
                    .param("password", "1111" )).andExpect(status().isOk())
         .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8));
        }

If you want just to check that it's an object in response you can use

 .andExpect(content().json("{}"));

empty array in response

 .andExpect(content().json("[]"));

array with two objects

.andExpect(content().json("[{}, {}]"));

if you want the exact result you can get it as a json string and then parse it.

 MvcResult result = this.mockMvc.perform(post("/login").param("username", "name")
                    .param("password", "1111" )).andExpect(status().isOk())
                    .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)).andReturn();
String resultJsonString = result.getResponse().getContentAsString();

You need a dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>