A Spring Boot application provides a REST API. It has several containers and is unit-tested. I have modified this application to add a new controller with a new PUT route, to upload a file.
When I run this application with mvn spring-boot:run
, I can access the new route via Postman. However, in my unit tests, I cannot.
My unit test autowires a WebApplicationContext into the test and creates a MockMVC from it, like so:
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
class NewControllerTest {
@Autowired
private WebApplicationContext ctx;
// ... more autowirings ...
private MockMvc mockMvc;
@Before
public void setUp() {
mockMvc = standaloneSetup(ctx).build();
}
// ... actual test cases ...
}
Then, within the test case, I use the route like this:
mockMvc.perform(put("/newctrl/route/" + param + "/img.jpg")
.contentType("application/octet-stream").content(data))
.andExpect(status().isOk());
where data
is a byte[]
array and param
is an integer generated at run time.
The API is accesed nearly the same way in several other test cases. The only difference is that in the other test cases, the request method is never PUT, and the content is always a string. All other test cases work.
My new test, however, produces an error message:
java.lang.AssertionError: Status expected:<200> but was:<404>
In the log, I find:
2016-11-27 20:01:22.263 WARN 15648 --- [ main] o.s.web.servlet.PageNotFound : No mapping found for HTTP request with URI [/newctrl/route/42/img.jpg] in DispatcherServlet with name ''
I use mvn spring-boot:run
and copy-paste the URL from the log entry to Postman. I attach an image and, voilá, it works.
Why, then, does my test not work?
EDIT: Excerpts from NewController:
@RequestMapping("/newctrl")
@RestController
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
public class NewController {
@RequestMapping(value = "/route/{param}/{filename:.+}")
public void theRoute(@PathVariable Long param, @PathVariable String filename,
HttpServletRequest request, HttpServletResponse response) throws IOException {
// ...
}
}