Reputation: 9758
I'm trying to write some tests and I facing the following exception, when I try to post
a byte array body:
error
java.lang.AssertionError: Status expected:<201> but was:<404>
> POST /api/foo
> WebTestClient-Request-Id: [1]
> Content-Length: [246444]
Content not available yet
< 404 Not Found
<
Content not available yet
My Test class is the following:
@AutoConfigureWebTestClient
@RunWith(SpringRunner.class)
@FixMethodOrder(NAME_ASCENDING)
@SpringBootTest(classes = Application.class)
public class ControllerTest {
@Inject
protected WebTestClient webClient;
@Test
public void testPostFile() throws Exception {
byte[] bytes;
try (InputStream is = getClass().getClassLoader().getResourceAsStream("static/binary-file.docx")) {
bytes = IOUtils.toByteArray(is);
}
webClient
.post()
.uri("/api/foo")
.body(BodyInserters.fromResource(new ByteArrayResource(bytes))))
.exchange()
.expectStatus().isCreated();
}
}
Is anyone facing the same problem, it seems it cannot load the resource properly
EDIT:
My Application Bootstrap class
@EnableWebFlux
@Configuration
@ComponentScan(basePackageClasses = SBApplication.class)
@EnableAutoConfiguration
public class SBApplication {
/**
* Spring Boot Main Entry
*
* @param args command line arguments
* @throws Exception on failure
*/
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = new SpringApplicationBuilder()
.sources(SBApplication.class)
.run(args);
}
}
My Controller Class:
@RestController
@RequestMapping("/api")
public class SBController {
// ...
@RequestMapping(
method = POST,
path = "{name}"
)
public Mono<ResponseEntity> store(
@PathVariable("name") String name,
@RequestBody byte[] body) {
// do stuff
return Mono.just(
ResponseEntity
.status(HttpStatus.CREATED)
.build()
);
}
}
Upvotes: 4
Views: 5286
Reputation: 9758
Eventually, the issues was that my Controller is configured via annotations. WebTestClient can only recognize mapping endpoints that are routed via the RouterFunction
.
In order to test a Controller which is configured with annotations such as my example you will need to initialize a MockMvc and with the corresponding annotation @AutoConfigureMockMvc
Finally, since reactor-core
is used we need to utilize MockMvcRequestBuilders.asyncDispatch
as follows:
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@FixMethodOrder(NAME_ASCENDING)
@SpringBootTest(classes = Application.class)
public class ControllerTest {
@Inject
protected MockMvc mockMvc;
@Test
public void testPostFile() throws Exception {
byte[] bytes;
try (InputStream is = getClass().getClassLoader().getResourceAsStream("static/binary-file.docx")) {
bytes = IOUtils.toByteArray(is);
}
MvcResult result = mockMvc.perform(
post("/api/foo")
.content(bytes)
)
.andExpect(request().asyncStarted())
.andReturn();
mockMvc.perform(asyncDispatch(result))
.andExpect(status().isCreated());
}
}
And finally everything works as expected!
Upvotes: 2