JUnit 5 @WebFluxTest test to a Flux @PostMapping using WebTestClient
I'm trying out Spring WebFlux using annotation controller and embedded mongodb (JDK11). I am trying to write @WebFluxTest for my @RestController, in particular, @PostMapping portion.
It's a just basic setup with @RestController, and @Repository.
In my @RestController:
@RestController
@RequestMapping("/address")
@AllArgsConstructor
public class AddressController {
private final AddressRepository addressRepository;
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(value = "/create")
public Flux<Address> create(@RequestBody Flux<Address> address) {
return address.flatMap(this.addressRepository::save);
}
}
In my test:
@ExtendWith(SpringExtension.class)
@WebFluxTest(AddressController.class)
public class AddressControllerTest {
@Autowired
private WebTestClient webTestClient;
@MockBean
private AddressRepository addressRepository;
@Test
@DisplayName("Create")
public void create() {
Flux<Address> addresses = Flux.just("Hello").map(add ->
Address.builder().id("5bf907ff2e21d401d4054a4d").street(add).build());
Address add = Address.builder().id("5bf907ff2e21d401d4054a4d").street("Hello").build();
when(this.addressRepository.saveAll(addresses)).thenReturn(addresses);
this.webTestClient
.post()
.uri("/address/create")
.body(addresses, Address.class)
.exchange()
.expectStatus().isCreated()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectBody(Address.class).isEqualTo(add);
}
}
And a very simple POJO:
@Data
@Builder
@Document
@AllArgsConstructor
@NoArgsConstructor
public class Address {
@Id
private String id;
private String street;
}
Question:
I want to be able to create the endpoint to allow creation of 0..* address.
How to correctly write the unit test so that I can mock the call in create()? If I do
when(this.addressRepository.save(add)).thenReturn(addresses);
then, it's a Mono
But if I do
when(this.addressRepository.saveAll(addresses)).thenReturn(addresses);
then it's not mocking the correct method call in create().
What is the correct way to write this unit test?
Thanks! If I didn't provide enough info, please let me know.
Update: I am able to create using Postman to my /address/create endpoint though.
java spring junit spring-webflux
|
show 3 more comments
I'm trying out Spring WebFlux using annotation controller and embedded mongodb (JDK11). I am trying to write @WebFluxTest for my @RestController, in particular, @PostMapping portion.
It's a just basic setup with @RestController, and @Repository.
In my @RestController:
@RestController
@RequestMapping("/address")
@AllArgsConstructor
public class AddressController {
private final AddressRepository addressRepository;
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(value = "/create")
public Flux<Address> create(@RequestBody Flux<Address> address) {
return address.flatMap(this.addressRepository::save);
}
}
In my test:
@ExtendWith(SpringExtension.class)
@WebFluxTest(AddressController.class)
public class AddressControllerTest {
@Autowired
private WebTestClient webTestClient;
@MockBean
private AddressRepository addressRepository;
@Test
@DisplayName("Create")
public void create() {
Flux<Address> addresses = Flux.just("Hello").map(add ->
Address.builder().id("5bf907ff2e21d401d4054a4d").street(add).build());
Address add = Address.builder().id("5bf907ff2e21d401d4054a4d").street("Hello").build();
when(this.addressRepository.saveAll(addresses)).thenReturn(addresses);
this.webTestClient
.post()
.uri("/address/create")
.body(addresses, Address.class)
.exchange()
.expectStatus().isCreated()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectBody(Address.class).isEqualTo(add);
}
}
And a very simple POJO:
@Data
@Builder
@Document
@AllArgsConstructor
@NoArgsConstructor
public class Address {
@Id
private String id;
private String street;
}
Question:
I want to be able to create the endpoint to allow creation of 0..* address.
How to correctly write the unit test so that I can mock the call in create()? If I do
when(this.addressRepository.save(add)).thenReturn(addresses);
then, it's a Mono
But if I do
when(this.addressRepository.saveAll(addresses)).thenReturn(addresses);
then it's not mocking the correct method call in create().
What is the correct way to write this unit test?
Thanks! If I didn't provide enough info, please let me know.
Update: I am able to create using Postman to my /address/create endpoint though.
java spring junit spring-webflux
I haven't read the whole the question, because it's way too long and actually asks several different things, which should be in separate questions. But your controller calls save(), and your test mocks saveAll().
– JB Nizet
Nov 24 '18 at 10:40
I have clean up my question to only focus on the unit test now. I understand that, but when I call save() in my mock, it will complain that it is not aFlux. Do let me know how I can properly write the unit test so that I can test my endpoint. The confusing portion would probably be because I will doing aflatMapbefore calling thesave(). So an example on how to write a proper test will be appreciated.
– user1778855
Nov 24 '18 at 10:49
save() returns a Mono. But you tell your mock to return a Flux.
– JB Nizet
Nov 24 '18 at 10:55
Precisely, I want to return aFluxbecause my endpoint can take aFlux. So it can take on0..*Addresses, save it toRepositoryand then return the result back. What I am not sure is, how can I write the unit test for it. So please do show me an example on how I can achieve it.
– user1778855
Nov 24 '18 at 10:57
1
You don't mock the code you're testing. What you mock is the dependency of the code you're testing, i.e. the repository. You want to tell the repository: when your save method is called, please return this Mono. But what you're doing is: when your save method is called, please return this Flux. So replace.thenReturn(addresses)by.thenReturn(Mono.just(theAddressThatTheRepositoryMustReturnInAMono). I think you should step back a little, and learn the principle of mocks and stubs, before diving into WebFlux and reactive programming, which is hard.
– JB Nizet
Nov 24 '18 at 12:27
|
show 3 more comments
I'm trying out Spring WebFlux using annotation controller and embedded mongodb (JDK11). I am trying to write @WebFluxTest for my @RestController, in particular, @PostMapping portion.
It's a just basic setup with @RestController, and @Repository.
In my @RestController:
@RestController
@RequestMapping("/address")
@AllArgsConstructor
public class AddressController {
private final AddressRepository addressRepository;
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(value = "/create")
public Flux<Address> create(@RequestBody Flux<Address> address) {
return address.flatMap(this.addressRepository::save);
}
}
In my test:
@ExtendWith(SpringExtension.class)
@WebFluxTest(AddressController.class)
public class AddressControllerTest {
@Autowired
private WebTestClient webTestClient;
@MockBean
private AddressRepository addressRepository;
@Test
@DisplayName("Create")
public void create() {
Flux<Address> addresses = Flux.just("Hello").map(add ->
Address.builder().id("5bf907ff2e21d401d4054a4d").street(add).build());
Address add = Address.builder().id("5bf907ff2e21d401d4054a4d").street("Hello").build();
when(this.addressRepository.saveAll(addresses)).thenReturn(addresses);
this.webTestClient
.post()
.uri("/address/create")
.body(addresses, Address.class)
.exchange()
.expectStatus().isCreated()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectBody(Address.class).isEqualTo(add);
}
}
And a very simple POJO:
@Data
@Builder
@Document
@AllArgsConstructor
@NoArgsConstructor
public class Address {
@Id
private String id;
private String street;
}
Question:
I want to be able to create the endpoint to allow creation of 0..* address.
How to correctly write the unit test so that I can mock the call in create()? If I do
when(this.addressRepository.save(add)).thenReturn(addresses);
then, it's a Mono
But if I do
when(this.addressRepository.saveAll(addresses)).thenReturn(addresses);
then it's not mocking the correct method call in create().
What is the correct way to write this unit test?
Thanks! If I didn't provide enough info, please let me know.
Update: I am able to create using Postman to my /address/create endpoint though.
java spring junit spring-webflux
I'm trying out Spring WebFlux using annotation controller and embedded mongodb (JDK11). I am trying to write @WebFluxTest for my @RestController, in particular, @PostMapping portion.
It's a just basic setup with @RestController, and @Repository.
In my @RestController:
@RestController
@RequestMapping("/address")
@AllArgsConstructor
public class AddressController {
private final AddressRepository addressRepository;
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(value = "/create")
public Flux<Address> create(@RequestBody Flux<Address> address) {
return address.flatMap(this.addressRepository::save);
}
}
In my test:
@ExtendWith(SpringExtension.class)
@WebFluxTest(AddressController.class)
public class AddressControllerTest {
@Autowired
private WebTestClient webTestClient;
@MockBean
private AddressRepository addressRepository;
@Test
@DisplayName("Create")
public void create() {
Flux<Address> addresses = Flux.just("Hello").map(add ->
Address.builder().id("5bf907ff2e21d401d4054a4d").street(add).build());
Address add = Address.builder().id("5bf907ff2e21d401d4054a4d").street("Hello").build();
when(this.addressRepository.saveAll(addresses)).thenReturn(addresses);
this.webTestClient
.post()
.uri("/address/create")
.body(addresses, Address.class)
.exchange()
.expectStatus().isCreated()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectBody(Address.class).isEqualTo(add);
}
}
And a very simple POJO:
@Data
@Builder
@Document
@AllArgsConstructor
@NoArgsConstructor
public class Address {
@Id
private String id;
private String street;
}
Question:
I want to be able to create the endpoint to allow creation of 0..* address.
How to correctly write the unit test so that I can mock the call in create()? If I do
when(this.addressRepository.save(add)).thenReturn(addresses);
then, it's a Mono
But if I do
when(this.addressRepository.saveAll(addresses)).thenReturn(addresses);
then it's not mocking the correct method call in create().
What is the correct way to write this unit test?
Thanks! If I didn't provide enough info, please let me know.
Update: I am able to create using Postman to my /address/create endpoint though.
java spring junit spring-webflux
java spring junit spring-webflux
edited Nov 24 '18 at 12:23
user1778855
asked Nov 24 '18 at 10:34
user1778855user1778855
92319
92319
I haven't read the whole the question, because it's way too long and actually asks several different things, which should be in separate questions. But your controller calls save(), and your test mocks saveAll().
– JB Nizet
Nov 24 '18 at 10:40
I have clean up my question to only focus on the unit test now. I understand that, but when I call save() in my mock, it will complain that it is not aFlux. Do let me know how I can properly write the unit test so that I can test my endpoint. The confusing portion would probably be because I will doing aflatMapbefore calling thesave(). So an example on how to write a proper test will be appreciated.
– user1778855
Nov 24 '18 at 10:49
save() returns a Mono. But you tell your mock to return a Flux.
– JB Nizet
Nov 24 '18 at 10:55
Precisely, I want to return aFluxbecause my endpoint can take aFlux. So it can take on0..*Addresses, save it toRepositoryand then return the result back. What I am not sure is, how can I write the unit test for it. So please do show me an example on how I can achieve it.
– user1778855
Nov 24 '18 at 10:57
1
You don't mock the code you're testing. What you mock is the dependency of the code you're testing, i.e. the repository. You want to tell the repository: when your save method is called, please return this Mono. But what you're doing is: when your save method is called, please return this Flux. So replace.thenReturn(addresses)by.thenReturn(Mono.just(theAddressThatTheRepositoryMustReturnInAMono). I think you should step back a little, and learn the principle of mocks and stubs, before diving into WebFlux and reactive programming, which is hard.
– JB Nizet
Nov 24 '18 at 12:27
|
show 3 more comments
I haven't read the whole the question, because it's way too long and actually asks several different things, which should be in separate questions. But your controller calls save(), and your test mocks saveAll().
– JB Nizet
Nov 24 '18 at 10:40
I have clean up my question to only focus on the unit test now. I understand that, but when I call save() in my mock, it will complain that it is not aFlux. Do let me know how I can properly write the unit test so that I can test my endpoint. The confusing portion would probably be because I will doing aflatMapbefore calling thesave(). So an example on how to write a proper test will be appreciated.
– user1778855
Nov 24 '18 at 10:49
save() returns a Mono. But you tell your mock to return a Flux.
– JB Nizet
Nov 24 '18 at 10:55
Precisely, I want to return aFluxbecause my endpoint can take aFlux. So it can take on0..*Addresses, save it toRepositoryand then return the result back. What I am not sure is, how can I write the unit test for it. So please do show me an example on how I can achieve it.
– user1778855
Nov 24 '18 at 10:57
1
You don't mock the code you're testing. What you mock is the dependency of the code you're testing, i.e. the repository. You want to tell the repository: when your save method is called, please return this Mono. But what you're doing is: when your save method is called, please return this Flux. So replace.thenReturn(addresses)by.thenReturn(Mono.just(theAddressThatTheRepositoryMustReturnInAMono). I think you should step back a little, and learn the principle of mocks and stubs, before diving into WebFlux and reactive programming, which is hard.
– JB Nizet
Nov 24 '18 at 12:27
I haven't read the whole the question, because it's way too long and actually asks several different things, which should be in separate questions. But your controller calls save(), and your test mocks saveAll().
– JB Nizet
Nov 24 '18 at 10:40
I haven't read the whole the question, because it's way too long and actually asks several different things, which should be in separate questions. But your controller calls save(), and your test mocks saveAll().
– JB Nizet
Nov 24 '18 at 10:40
I have clean up my question to only focus on the unit test now. I understand that, but when I call save() in my mock, it will complain that it is not a
Flux. Do let me know how I can properly write the unit test so that I can test my endpoint. The confusing portion would probably be because I will doing a flatMap before calling the save(). So an example on how to write a proper test will be appreciated.– user1778855
Nov 24 '18 at 10:49
I have clean up my question to only focus on the unit test now. I understand that, but when I call save() in my mock, it will complain that it is not a
Flux. Do let me know how I can properly write the unit test so that I can test my endpoint. The confusing portion would probably be because I will doing a flatMap before calling the save(). So an example on how to write a proper test will be appreciated.– user1778855
Nov 24 '18 at 10:49
save() returns a Mono. But you tell your mock to return a Flux.
– JB Nizet
Nov 24 '18 at 10:55
save() returns a Mono. But you tell your mock to return a Flux.
– JB Nizet
Nov 24 '18 at 10:55
Precisely, I want to return a
Flux because my endpoint can take a Flux. So it can take on 0..* Addresses, save it to Repository and then return the result back. What I am not sure is, how can I write the unit test for it. So please do show me an example on how I can achieve it.– user1778855
Nov 24 '18 at 10:57
Precisely, I want to return a
Flux because my endpoint can take a Flux. So it can take on 0..* Addresses, save it to Repository and then return the result back. What I am not sure is, how can I write the unit test for it. So please do show me an example on how I can achieve it.– user1778855
Nov 24 '18 at 10:57
1
1
You don't mock the code you're testing. What you mock is the dependency of the code you're testing, i.e. the repository. You want to tell the repository: when your save method is called, please return this Mono. But what you're doing is: when your save method is called, please return this Flux. So replace
.thenReturn(addresses) by .thenReturn(Mono.just(theAddressThatTheRepositoryMustReturnInAMono). I think you should step back a little, and learn the principle of mocks and stubs, before diving into WebFlux and reactive programming, which is hard.– JB Nizet
Nov 24 '18 at 12:27
You don't mock the code you're testing. What you mock is the dependency of the code you're testing, i.e. the repository. You want to tell the repository: when your save method is called, please return this Mono. But what you're doing is: when your save method is called, please return this Flux. So replace
.thenReturn(addresses) by .thenReturn(Mono.just(theAddressThatTheRepositoryMustReturnInAMono). I think you should step back a little, and learn the principle of mocks and stubs, before diving into WebFlux and reactive programming, which is hard.– JB Nizet
Nov 24 '18 at 12:27
|
show 3 more comments
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53457254%2fjunit-5-webfluxtest-test-to-a-flux-postmapping-using-webtestclient%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53457254%2fjunit-5-webfluxtest-test-to-a-flux-postmapping-using-webtestclient%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I haven't read the whole the question, because it's way too long and actually asks several different things, which should be in separate questions. But your controller calls save(), and your test mocks saveAll().
– JB Nizet
Nov 24 '18 at 10:40
I have clean up my question to only focus on the unit test now. I understand that, but when I call save() in my mock, it will complain that it is not a
Flux. Do let me know how I can properly write the unit test so that I can test my endpoint. The confusing portion would probably be because I will doing aflatMapbefore calling thesave(). So an example on how to write a proper test will be appreciated.– user1778855
Nov 24 '18 at 10:49
save() returns a Mono. But you tell your mock to return a Flux.
– JB Nizet
Nov 24 '18 at 10:55
Precisely, I want to return a
Fluxbecause my endpoint can take aFlux. So it can take on0..*Addresses, save it toRepositoryand then return the result back. What I am not sure is, how can I write the unit test for it. So please do show me an example on how I can achieve it.– user1778855
Nov 24 '18 at 10:57
1
You don't mock the code you're testing. What you mock is the dependency of the code you're testing, i.e. the repository. You want to tell the repository: when your save method is called, please return this Mono. But what you're doing is: when your save method is called, please return this Flux. So replace
.thenReturn(addresses)by.thenReturn(Mono.just(theAddressThatTheRepositoryMustReturnInAMono). I think you should step back a little, and learn the principle of mocks and stubs, before diving into WebFlux and reactive programming, which is hard.– JB Nizet
Nov 24 '18 at 12:27