JUnit 5 @WebFluxTest test to a Flux @PostMapping using WebTestClient












0















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.










share|improve this question

























  • 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













  • 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






  • 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
















0















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.










share|improve this question

























  • 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













  • 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






  • 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














0












0








0








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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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











  • 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





    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 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











  • 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





    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












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
});


}
});














draft saved

draft discarded


















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
















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Ottavio Pratesi

Tricia Helfer

15 giugno