title: Testing Rest Controllers in Spring Boot using Standalone MockMvc
body: <p>I am trying to put some unit/integration tests on my code,</p>
  
  <p>I've a typical rest application build with spring boot, I am trying to test the <a href="https://github.com/MuhammadHewedy/match/blob/master/match-api/src/main/java/match/controllers/AdminController.java#L45" rel="nofollow noreferrer">AdminController <code>save</code></a> method:</p>
  
  <pre><code>@RequestMapping(method = RequestMethod.POST)
  public ResponseEntity&lt;Void&gt; save(@RequestBody @Valid User user) {
      user.setRole(Role.ROLE_ADMIN);
      user.setPassword(passwordEncoder.encode(user.getPassword()));
      return super.save(user);
  }
  </code></pre>
  
  <p>The method is straight forward and it check the duplicate through the database, as I making the User object's <code>username</code> property unique:</p>
  
  <pre><code>@NotNull
  @Column(updatable = false, unique = true)
  private String username;
  </code></pre>
  
  <p>When I try to save two users with the same username, the server refuses with this <code>out-of-the-box</code> JSON output: (Http code: 500)</p>
  
  <pre><code>{
    "timestamp": 1473942296273,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "org.springframework.dao.DataIntegrityViolationException",
    "message": "could not execute statement; SQL [n/a]; constraint [uk_sb8bbouer5wak8vyiiy4pf2bx]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
    "path": "/api/admins"
  }
  </code></pre>
  
  <p>I am ok with this, as it appears spring boot default behaviour is to send errors to <code>/error</code> (which is handled by <code>BasicErrorController</code>) that handle the exception and return this pretty json output:</p>
  
  <pre><code>[dispatcherServlet]             : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [uk_sb8bbouer5wak8vyiiy4pf2bx]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
  DispatcherServlet               : DispatcherServlet with name 'dispatcherServlet' processing POST request for [/error]
  RequestMappingHandlerMapping    : Looking up handler method for path /error
  RequestMappingHandlerMapping    : Returning handler method [public org.springframework.http.ResponseEntity&lt;java.util.Map&lt;java.lang.String, java.lang.Object&gt;&gt; org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
  DefaultListableBeanFactory      : Returning cached instance of singleton bean 'basicErrorController'
  OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
  HttpEntityMethodProcessor       : Written [{timestamp=Thu Sep 15 16:09:07 AST 2016, status=500, error=Internal Server Error, exception=org.springframework.dao.DataIntegrityViolationException, message=could not execute statement; SQL [n/a]; constraint [uk_sb8bbouer5wak8vyiiy4pf2bx]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement, path=/api/admins}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@1482cc8]
  </code></pre>
  
  <p>But when I try to test this using mockito (<a href="https://github.com/MuhammadHewedy/match/blob/master/match-api/src/test/java/match/controllers/AdminControllerIntTest.java#L83" rel="nofollow noreferrer">see full test class</a>):</p>
  
  <pre><code>@Transactional
  @Test
  public void testSaveDupValidUser() throws Exception {
      User user = new User();
      user.setUsername("admin");
  
      this.mockMvc.perform(post("/api/admins")
              .contentType(TestUtil.APPLICATION_JSON_UTF8)
              .content(TestUtil.convertObjectToJsonBytes(user)))
      .andDo(print())
      .andExpect(status().isOk());
  
      this.mockMvc.perform(post("/api/admins")
              .contentType(TestUtil.APPLICATION_JSON_UTF8)
              .content(TestUtil.convertObjectToJsonBytes(user)))
      .andDo(print())
      .andExpect(status().isInternalServerError());
  }
  </code></pre>
  
  <p>instead of getting <code>500</code> internal server error, I got the following exception from junit:</p>
  
  <pre><code>org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["UK_SB8BBOUER5WAK8VYIIY4PF2BX_INDEX_3 ON PUBLIC.""user""(USERNAME) VALUES ('admin', 1)"; SQL statement:
  insert into "user" (id, created_by, created_date, modified_by, modified_date, enabled, password, role, username) values (null, ?, ?, ?, ?, ?, ?, ?, ?) [23505-192]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
      at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
  </code></pre>
  
  <p>So, My question is:</p>
  
  <p>How to enable make the dispatcher servlet to forward to /error and return the same error as if the application is running (not under test)?</p>
  
  <p>while keeping use MockMvc standealone, and without writing code in the rest method to handle the exception and return code <code>500</code>.</p>
  
  <p>(I think this might be impossible, so Should I assert on the exception instead? Or should I use <code>webAppContextSetup</code>? What is the best practice here? - <code>jHipster</code> for example uses standalone MockMvc in all its tests)</p>
  
  <p>Related: <a href="https://stackoverflow.com/questions/31566390/unit-test-spring-missingservletrequestparameterexception-json-response">unit test Spring MissingServletRequestParameterException JSON response</a> (but mine not fixed)</p>