I've got problem with mock. It's null. Could you help me?
- UsersService
public interface UsersService {
Mono<GetUserDto> findById(String id);
Mono<GetUserDto> findByUsername(String username);
Mono<CreateUserResponseDto> create(Mono<CreateUserDto> createUserDtoMono);
}
- RoutingHandlers
package com.app.routing;
import com.app.dto.CreateUserDto;
import com.app.service.UsersService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@Component
@RequiredArgsConstructor
public class RoutingHandlers {
private final UsersService usersService;
public Mono<ServerResponse> register(ServerRequest serverRequest) {
Mono<CreateUserDto> createUserDtoMono = serverRequest.bodyToMono(CreateUserDto.class);
var create = usersService.create(createUserDtoMono);
return toServerResponse(create, HttpStatus.CREATED);
}
public Mono<ServerResponse> findByUsername(ServerRequest serverRequest) {
String username = serverRequest.pathVariable("username");
return toServerResponse(usersService.findByUsername(username), HttpStatus.OK);
}
public Mono<ServerResponse> findById(ServerRequest serverRequest) {
String id = serverRequest.pathVariable("id");
return toServerResponse(usersService.findById(id), HttpStatus.OK);
}
private static <T> Mono<ServerResponse> toServerResponse(Mono<T> mono, HttpStatus status) {
return mono
.flatMap(item -> ServerResponse
.status(status)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(item)))
.doOnError(err -> {
System.out.println("---------------------------- ERROR -----------------------------");
System.out.println(err);
System.out.println("----------------------------------------------------------------");
})
.onErrorResume(e -> ServerResponse
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(e.getMessage())));
}
}
- Routing
package com.app.routing;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
@Configuration
public class Routing {
@Bean
public RouterFunction<ServerResponse> routerFunction(RoutingHandlers routingHandlers) {
return nest(
path("/users"),
route(POST("").and(accept(MediaType.APPLICATION_JSON)), routingHandlers::register)
.andRoute(GET("/username/{username}").and(accept(MediaType.APPLICATION_JSON)), routingHandlers::findByUsername)
.andRoute(GET("/id/{id}").and(accept(MediaType.APPLICATION_JSON)), routingHandlers::findById)
);
}
}
- RoutingTest
package com.app;
import com.app.dto.CreateUserDto;
import com.app.dto.CreateUserResponseDto;
import com.app.routing.Routing;
import com.app.routing.RoutingHandlers;
import com.app.service.UsersService;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Mono;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {RoutingHandlers.class, Routing.class})
@WebFluxTest
class RoutingTest {
@Autowired
private ApplicationContext applicationContext;
@MockBean
private UsersService usersService;
private WebTestClient webTestClient;
@BeforeEach
public void setup() {
webTestClient = WebTestClient.bindToApplicationContext(applicationContext).build();
}
@Test
public void test1() {
var userBody = CreateUserDto
.builder()
.username("u")
.password("1234")
.passwordConfirmation("1234")
.build();
var body = Mono.just(userBody);
var userResponse = CreateUserResponseDto
.builder()
.id("1")
.username("u")
.build();
var response = Mono.just(userResponse);
Mockito
.when(usersService.create(body))
.thenReturn(response);
webTestClient
.post()
.uri("/users")
.accept(MediaType.APPLICATION_JSON)
.body(body, CreateUserDto.class)
.exchange()
.expectStatus().isCreated()
.expectBody(CreateUserResponseDto.class)
.value(createUserResponseDto -> {
Assertions.assertThat(createUserResponseDto)
.hasFieldOrPropertyWithValue("username", "u")
.hasFieldOrPropertyWithValue("password", "1234");
});
}
}
- DTOs
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class CreateUserDto {
private String username;
private String password;
private String passwordConfirmation;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class CreateUserResponseDto {
private String id;
private String username;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class GetUserDto {
private String id;
private String username;
private String password;
}
After I ran test I got error: Cannot invoke "reactor.core.publisher.Mono.flatMap(java.util.function.Function)" because "mono" is null. In RoutingHandlers in register method instance called create is null:
public Mono<ServerResponse> register(ServerRequest serverRequest) {
Mono<CreateUserDto> createUserDtoMono = serverRequest.bodyToMono(CreateUserDto.class);
var create = usersService.create(createUserDtoMono);
return toServerResponse(create, HttpStatus.CREATED);
}
Aucun commentaire:
Enregistrer un commentaire