parent
fa1c5598b0
commit
7c93d40044
|
@ -3,7 +3,6 @@
|
||||||
This module contains articles about Spring 5 WebFlux
|
This module contains articles about Spring 5 WebFlux
|
||||||
|
|
||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
|
||||||
- [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable)
|
- [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable)
|
||||||
- [Comparison Between Mono’s doOnNext() and doOnSuccess()](https://www.baeldung.com/mono-doonnext-doonsuccess)
|
- [Comparison Between Mono’s doOnNext() and doOnSuccess()](https://www.baeldung.com/mono-doonnext-doonsuccess)
|
||||||
- [How to Access the First Element of a Flux](https://www.baeldung.com/java-flux-first-element)
|
- [How to Access the First Element of a Flux](https://www.baeldung.com/java-flux-first-element)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>spring-5-webflux-2</artifactId>
|
<artifactId>spring-5-webflux-2</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
|
@ -41,6 +41,10 @@ public class Item {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Item{" + "id='" + _id + '\'' + ", name='" + name + '\'' + ", price=" + price + '}';
|
return "Item{" +
|
||||||
|
"id='" + _id + '\'' +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", price=" + price +
|
||||||
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,7 @@ public class ItemService {
|
||||||
|
|
||||||
public ItemService(ItemRepository repository) {
|
public ItemService(ItemRepository repository) {
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.cache = Caffeine.newBuilder()
|
this.cache = Caffeine.newBuilder().build(this::getItem_withCaffeine);
|
||||||
.build(this::getItem_withCaffeine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable("items")
|
@Cacheable("items")
|
||||||
|
@ -31,14 +30,11 @@ public class ItemService {
|
||||||
|
|
||||||
@Cacheable("items")
|
@Cacheable("items")
|
||||||
public Mono<Item> getItem_withCache(String id) {
|
public Mono<Item> getItem_withCache(String id) {
|
||||||
return repository.findById(id)
|
return repository.findById(id).cache();
|
||||||
.cache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable("items")
|
@Cacheable("items")
|
||||||
public Mono<Item> getItem_withCaffeine(String id) {
|
public Mono<Item> getItem_withCaffeine(String id) {
|
||||||
return cache.asMap()
|
return cache.asMap().computeIfAbsent(id, k -> repository.findById(id).cast(Item.class));
|
||||||
.computeIfAbsent(id, k -> repository.findById(id)
|
|
||||||
.cast(Item.class));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package com.baeldung.webflux.exceptionhandeling.controller;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException;
|
|
||||||
import com.baeldung.webflux.exceptionhandeling.repository.UserRepository;
|
|
||||||
import com.baeldung.webflux.zipwhen.model.User;
|
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class UserController {
|
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public UserController(UserRepository userRepository) {
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/user/{id}")
|
|
||||||
public Mono<User> getUserByIdThrowingException(@PathVariable String id) {
|
|
||||||
return userRepository.findById(id)
|
|
||||||
.switchIfEmpty(Mono.error(new NotFoundException("User not found")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/user/{id}")
|
|
||||||
public Mono<User> getUserByIdUsingMonoError(@PathVariable String id) {
|
|
||||||
return userRepository.findById(id)
|
|
||||||
.switchIfEmpty(Mono.error(() -> new NotFoundException("User not found")));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package com.baeldung.webflux.exceptionhandeling.ex;
|
|
||||||
|
|
||||||
public class NotFoundException extends RuntimeException {
|
|
||||||
|
|
||||||
public NotFoundException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotFoundException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package com.baeldung.webflux.exceptionhandeling.model;
|
|
||||||
|
|
||||||
public class User {
|
|
||||||
private String id;
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User(String userId, String userName) {
|
|
||||||
this.id=userId;
|
|
||||||
this.username=userName;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
package com.baeldung.webflux.exceptionhandeling.repository;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import com.baeldung.webflux.zipwhen.model.User;
|
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
@Repository
|
|
||||||
public class UserRepository {
|
|
||||||
private final Map<String, User> userDatabase = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public UserRepository() {
|
|
||||||
userDatabase.put("1", new User("1", "John Doe"));
|
|
||||||
userDatabase.put("2", new User("2", "Jane Smith"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mono<User> findById(String id) {
|
|
||||||
return Mono.justOrEmpty(userDatabase.get(id));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,9 @@
|
||||||
package com.baeldung.webflux.filerecord;
|
package com.baeldung.webflux.filerecord;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class FileRecord {
|
public class FileRecord {
|
||||||
@Id
|
@Id
|
||||||
private int id;
|
private int id;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.baeldung.webflux.filerecord;
|
package com.baeldung.webflux.filerecord;
|
||||||
|
|
||||||
|
import io.r2dbc.spi.ConnectionFactory;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -7,8 +8,6 @@ import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer;
|
import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer;
|
||||||
import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator;
|
import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator;
|
||||||
|
|
||||||
import io.r2dbc.spi.ConnectionFactory;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class FileRecordApplication {
|
public class FileRecordApplication {
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package com.baeldung.webflux.filerecord;
|
package com.baeldung.webflux.filerecord;
|
||||||
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
import org.springframework.http.codec.multipart.FilePart;
|
import org.springframework.http.codec.multipart.FilePart;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
public class FileRecordController {
|
public class FileRecordController {
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ public class FileRecordController {
|
||||||
FileRecord fileRecord = new FileRecord();
|
FileRecord fileRecord = new FileRecord();
|
||||||
|
|
||||||
return filePartFlux.flatMap(filePart -> filePart.transferTo(Paths.get(filePart.filename()))
|
return filePartFlux.flatMap(filePart -> filePart.transferTo(Paths.get(filePart.filename()))
|
||||||
.then(Mono.just(filePart.filename())))
|
.then(Mono.just(filePart.filename())))
|
||||||
.collectList()
|
.collectList()
|
||||||
.flatMap(filenames -> {
|
.flatMap(filenames -> {
|
||||||
fileRecord.setFilenames(filenames);
|
fileRecord.setFilenames(filenames);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.baeldung.webflux.filerecord;
|
package com.baeldung.webflux.filerecord;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.baeldung.webflux.model;
|
package com.baeldung.webflux.model;
|
||||||
|
|
||||||
|
|
||||||
public class Payment {
|
public class Payment {
|
||||||
private final int amount;
|
private final int amount;
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,10 @@ public class EmailService {
|
||||||
|
|
||||||
public Mono<Boolean> sendEmail(String userId) {
|
public Mono<Boolean> sendEmail(String userId) {
|
||||||
return userService.getUser(userId)
|
return userService.getUser(userId)
|
||||||
.flatMap(user -> {
|
.flatMap(user -> {
|
||||||
System.out.println("Sending email to: " + user.getEmail());
|
System.out.println("Sending email to: " + user.getEmail());
|
||||||
return Mono.just(true);
|
return Mono.just(true);
|
||||||
})
|
})
|
||||||
.defaultIfEmpty(false);
|
.defaultIfEmpty(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,16 +28,16 @@ public class UserController {
|
||||||
public Mono<ResponseEntity<String>> combineAllDataFor(@PathVariable String userId) {
|
public Mono<ResponseEntity<String>> combineAllDataFor(@PathVariable String userId) {
|
||||||
Mono<User> userMono = userService.getUser(userId);
|
Mono<User> userMono = userService.getUser(userId);
|
||||||
Mono<Boolean> emailSentMono = emailService.sendEmail(userId)
|
Mono<Boolean> emailSentMono = emailService.sendEmail(userId)
|
||||||
.subscribeOn(Schedulers.parallel());
|
.subscribeOn(Schedulers.parallel());
|
||||||
Mono<String> databaseResultMono = userMono.flatMap(user -> databaseService.saveUserData(user)
|
Mono<String> databaseResultMono = userMono.flatMap(user -> databaseService.saveUserData(user)
|
||||||
.map(Object::toString));
|
.map(Object::toString));
|
||||||
|
|
||||||
return userMono.zipWhen(user -> emailSentMono, Tuples::of)
|
return userMono.zipWhen(user -> emailSentMono, Tuples::of)
|
||||||
.zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> {
|
.zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> {
|
||||||
User user = tuple.getT1();
|
User user = tuple.getT1();
|
||||||
Boolean emailSent = tuple.getT2();
|
Boolean emailSent = tuple.getT2();
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult);
|
.body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<appender name="Console"
|
<appender name="Console"
|
||||||
class="ch.qos.logback.core.ConsoleAppender">
|
class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
<Pattern>
|
<Pattern>
|
||||||
%black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
|
%black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.baeldung.webflux.caching;
|
package com.baeldung.webflux.caching;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -13,10 +12,13 @@ import org.testcontainers.utility.DockerImageName;
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@ActiveProfiles("cache")
|
@ActiveProfiles("cache")
|
||||||
public class MonoFluxResultCachingLiveTest {
|
public class MonoFluxResultCachingLiveTest {
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
ItemService itemService;
|
ItemService itemService;
|
||||||
|
|
||||||
|
@ -28,34 +30,32 @@ public class MonoFluxResultCachingLiveTest {
|
||||||
registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
|
registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenItem_whenGetItemIsCalled_thenMonoIsCached() {
|
public void givenItem_whenGetItemIsCalled_thenMonoIsCached() {
|
||||||
Mono<Item> glass = itemService.save(new Item("glass", 1.00));
|
Mono<Item> glass = itemService.save(new Item("glass", 1.00));
|
||||||
|
|
||||||
String id = glass.block()
|
String id = glass.block().get_id();
|
||||||
.get_id();
|
|
||||||
|
|
||||||
Mono<Item> mono = itemService.getItem(id);
|
Mono<Item> mono = itemService.getItem(id);
|
||||||
Item item = mono.block();
|
Item item = mono.block();
|
||||||
|
|
||||||
assertThat(item).isNotNull();
|
assertThat(item).isNotNull();
|
||||||
assertThat(item.getName()).isEqualTo("glass");
|
assertThat(item.getName()).isEqualTo("glass");
|
||||||
assertThat(item.getPrice()).isEqualTo(1.00);
|
assertThat(item.getPrice()).isEqualTo(1.00);
|
||||||
|
|
||||||
Mono<Item> mono2 = itemService.getItem(id);
|
Mono<Item> mono2 = itemService.getItem(id);
|
||||||
Item item2 = mono2.block();
|
Item item2 = mono2.block();
|
||||||
|
|
||||||
assertThat(item2).isNotNull();
|
assertThat(item2).isNotNull();
|
||||||
assertThat(item2.getName()).isEqualTo("glass");
|
assertThat(item2.getName()).isEqualTo("glass");
|
||||||
assertThat(item2.getPrice()).isEqualTo(1.00);
|
assertThat(item2.getPrice()).isEqualTo(1.00);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenItem_whenGetItemWithCacheIsCalled_thenMonoResultIsCached() {
|
public void givenItem_whenGetItemWithCacheIsCalled_thenMonoResultIsCached() {
|
||||||
Mono<Item> glass = itemService.save(new Item("glass", 1.00));
|
Mono<Item> glass = itemService.save(new Item("glass", 1.00));
|
||||||
|
|
||||||
String id = glass.block()
|
String id = glass.block().get_id();
|
||||||
.get_id();
|
|
||||||
|
|
||||||
Mono<Item> mono = itemService.getItem_withCache(id);
|
Mono<Item> mono = itemService.getItem_withCache(id);
|
||||||
Item item = mono.block();
|
Item item = mono.block();
|
||||||
|
@ -76,8 +76,7 @@ public class MonoFluxResultCachingLiveTest {
|
||||||
public void givenItem_whenGetItemWithCaffeineIsCalled_thenMonoResultIsCached() {
|
public void givenItem_whenGetItemWithCaffeineIsCalled_thenMonoResultIsCached() {
|
||||||
Mono<Item> glass = itemService.save(new Item("glass", 1.00));
|
Mono<Item> glass = itemService.save(new Item("glass", 1.00));
|
||||||
|
|
||||||
String id = glass.block()
|
String id = glass.block().get_id();
|
||||||
.get_id();
|
|
||||||
|
|
||||||
Mono<Item> mono = itemService.getItem_withCaffeine(id);
|
Mono<Item> mono = itemService.getItem_withCaffeine(id);
|
||||||
Item item = mono.block();
|
Item item = mono.block();
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
package com.baeldung.webflux.exceptionhandeling;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
import reactor.test.StepVerifier;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.baeldung.webflux.exceptionhandeling.controller.UserController;
|
|
||||||
import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException;
|
|
||||||
import com.baeldung.webflux.exceptionhandeling.repository.UserRepository;
|
|
||||||
|
|
||||||
public class UserControllerUnitTest {
|
|
||||||
@Mock
|
|
||||||
private UserRepository userRepository;
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private UserController userController;
|
|
||||||
|
|
||||||
public UserControllerUnitTest() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetUserByIdUsingMonoError_UserNotFound() {
|
|
||||||
String userId = "3";
|
|
||||||
when(userRepository.findById(userId)).thenReturn(Mono.empty());
|
|
||||||
StepVerifier.create(userController.getUserByIdUsingMonoError(userId))
|
|
||||||
.expectError(NotFoundException.class)
|
|
||||||
.verify();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetUserByIdThrowingException_UserNotFound() {
|
|
||||||
String userId = "3";
|
|
||||||
when(userRepository.findById(userId)).thenReturn(Mono.empty());
|
|
||||||
assertThrows(NotFoundException.class, () -> userController.getUserByIdThrowingException(userId)
|
|
||||||
.block());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package com.baeldung.webflux.filerecord;
|
package com.baeldung.webflux.filerecord;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -18,9 +13,13 @@ import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(SpringExtension.class)
|
@ExtendWith(SpringExtension.class)
|
||||||
@SpringBootTest(classes = FileRecordController.class)
|
@SpringBootTest(classes = FileRecordController.class)
|
||||||
@ContextConfiguration(classes = { FileRecordController.class })
|
@ContextConfiguration(classes = { FileRecordController.class })
|
||||||
|
|
|
@ -7,7 +7,6 @@ import java.util.Optional;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import com.baeldung.webflux.model.Payment;
|
import com.baeldung.webflux.model.Payment;
|
||||||
|
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
|
@ -25,19 +25,19 @@ public class UserControllerUnitTest {
|
||||||
User user = new User(userId, "John Doe");
|
User user = new User(userId, "John Doe");
|
||||||
|
|
||||||
Mockito.when(userService.getUser(userId))
|
Mockito.when(userService.getUser(userId))
|
||||||
.thenReturn(Mono.just(user));
|
.thenReturn(Mono.just(user));
|
||||||
Mockito.when(emailService.sendEmail(userId))
|
Mockito.when(emailService.sendEmail(userId))
|
||||||
.thenReturn(Mono.just(true));
|
.thenReturn(Mono.just(true));
|
||||||
Mockito.when(databaseService.saveUserData(user))
|
Mockito.when(databaseService.saveUserData(user))
|
||||||
.thenReturn(Mono.just(true));
|
.thenReturn(Mono.just(true));
|
||||||
|
|
||||||
UserController userController = new UserController(userService, emailService, databaseService);
|
UserController userController = new UserController(userService, emailService, databaseService);
|
||||||
|
|
||||||
Mono<ResponseEntity<String>> responseMono = userController.combineAllDataFor(userId);
|
Mono<ResponseEntity<String>> responseMono = userController.combineAllDataFor(userId);
|
||||||
|
|
||||||
StepVerifier.create(responseMono)
|
StepVerifier.create(responseMono)
|
||||||
.expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody()
|
.expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody()
|
||||||
.equals("Response: " + user + ", Email Sent: true, Database Result: " + true))
|
.equals("Response: " + user + ", Email Sent: true, Database Result: " + true))
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue