-1

So I'm learning Unit Testcases for SpringMVC and also pretty new to Spring-Boot in general.

I wanna write a unit test case for this mvc controller method that I have

@RequestMapping("/college")
@RestController
public class college {

    @PersistenceContext
    private EntityManager em;

    @RequestMapping(value = "/request", method = RequestMethod.GET)
    public List<Object> display() {
        //List<StudentDB> val = temp.findAll();
        Query query = em.createNativeQuery("SELECT * FROM STUDENT");
        List<Object> val = (List<Object>)query.getResultList();
        return val;
    }

I tried writing something like this -

@SpringBootTest
public class MockTestCollegeController {

    @Mock
    private EntityManager em;

    @InjectMocks
    private college col;

    @Autowired
    private MockMvc mockMvc;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(col).build();
    }



    @Test
        public void dets() throws Exception 
       { RequestBuilder req =MockMvcRequestBuilders.get("/college/request").accept(MediaType.APPLICATION_JSON);
                    MockHttpServletResponse result = mockMvc.perform(req).andReturn().getResponse();
                    //System.out.println(result.getResponse().getContentAsString());
                    //String expected = "{id:1,content:'Hello, World!'}";
                    Query query = em.createNativeQuery("SELECT * FROM STUDENT");
                    List<Object> val = (List<Object>)query.getResultList();
                    Assert.assertEquals(val, result);
                        }

But its giving me a NullPointerException at -

MockHttpServletResponse result = mockMvc.perform(req).andReturn().getResponse();

Any suggestions?

tryhard
  • 1
  • 1
  • Do not use an entitymanager in your controller. Learn about three tier architechture – Jens Jan 11 '19 at 22:02
  • Okay, but still just learning it, i'm keeping it simple for now, I plan on adding service and dal soon. – tryhard Jan 11 '19 at 22:12

1 Answers1

0

If your goal is to purely test the controller use @WebMvcTest and @MockBean. This will allow you to test the request mappings while the business logic should be extracted to a new @Repository bean and tested separately with a test hitting an in-memory database.

EntityManager should be tested by hitting an actual database because that's the most sane way to check ORM configuration. You can use H2 in-memory database if your entity mappings are portable.

You should separate @Controller, @Service and @Repository layers of your application. Doing so will make your code more maintainable and easier to test.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
  • I did think about using H-2 for in memory testing, but the thing is , I plan on using MS-SQL stored procedure in my project later, and H-2 doesn't seem to support that. So I wanted to try testing the controllers using the Mockito and then do some more integration testing later with an actual DB. – tryhard Jan 11 '19 at 22:11
  • @tryhard Instead you could use Docker and [Test Containers](https://www.testcontainers.org/) to spin up [a MSSQL database container](https://learn.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-2017) just for the tests. – Karol Dowbecki Jan 11 '19 at 22:12