Я пытаюсь исправить testGetAllUsers()
, но он продолжает возвращаться java.lang.AssertionError: No value at JSON path "[0].id"
. По сути, это база данных в памяти, которая должна воссоздавать себя при каждом запуске.
Вторая проблема заключается в том, что поле role
всегда равно нулю, даже если оно установлено на moderator
. Может быть, это потому, что я добавил это позже? Как мне это исправить? Удаление test-db
файлов не работает.
MockHttpServletRequest:
HTTP Method = GET
Request URI = /api/users
Parameters = {}
Headers = []
Body = null
Session Attrs = {}
Handler:
Type = com.mse.wcp.forum.controllers.UserController
Method = com.mse.wcp.forum.controllers.UserController#getAll()
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Content-Type:"application/json"]
Content type = application/json
Body = [{"username":"admin","password":"123","firstName":"admin","lastName":"admin","role":null}]
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: No value at JSON path "[0].id"
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:295)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:98)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.lambda$value$2(JsonPathResultMatchers.java:111)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:196)
at com.mse.wcp.forum.controllers.UserControllerTest.testGetAllUsers(UserControllerTest.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: com.jayway.jsonpath.PathNotFoundException: No results for path: $[0]['id']
at com.jayway.jsonpath.internal.path.EvaluationContextImpl.getValue(EvaluationContextImpl.java:133)
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187)
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:345)
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:329)
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:292)
... 67 more
2020-03-06 16:50:52.782 INFO 47704 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2020-03-06 16:50:52.784 INFO 47704 --- [extShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-03-06 16:50:52.784 INFO 47704 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2020-03-06 16:50:52.786 INFO 47704 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
В тестах используется следующая конфигурация:
test.properties
# Server
server.port=8083
# Hibernate settings
spring.jpa.hibernate.ddl-auto=create
# Datasource configuration
spring.datasource.url=jdbc:h2:file:~/test-db
spring.datasource.username=sa
spring.datasource.password=
UserControllerTest. java
package com.mse.wcp.forum.controllers;
import com.google.gson.Gson;
import com.mse.wcp.forum.persistence.entities.UserEntity;
import com.mse.wcp.forum.services.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:test.properties")
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private UserService userService;
@Test
public void testGetAllUsers() throws Exception {
UserEntity userEntity = UserEntity
.builder()
.username("admin")
.password("123")
.firstName("admin")
.lastName("admin")
.role("moderator")
.build();
userService.create(userEntity);
mockMvc.perform(get("/api/users"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.length()*").value(1))
.andExpect(jsonPath("[0].id").value(1))
.andExpect(jsonPath("[0].username").value("admin"));
}
@Test
public void testGetUser() {
}
@Test
public void testCreateUser() throws Exception {
UserEntity userEntity = UserEntity
.builder()
.username("admin")
.password("123")
.firstName("admin")
.lastName("admin")
.role("moderator")
.build();
userService.create(userEntity);
Optional<UserEntity> userEntity2 = userService.get(1L);
assertTrue(userEntity2.isPresent());
Gson gson = new Gson();
String json = gson.toJson(userEntity);
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk());
}
@Test
public void testUpdateUser() {
}
@Test
public void testDeleteUser() {
}
}
UserService. java
package com.mse.wcp.forum.services;
import com.mse.wcp.forum.mappers.UserMapper;
import com.mse.wcp.forum.persistence.entities.UserEntity;
import com.mse.wcp.forum.persistence.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private UserMapper mapper;
public List<UserEntity> getAll() {
return userRepository.findAll();
}
public Optional<UserEntity> get(Long id) {
return userRepository.findById(id);
}
public Optional<UserEntity> create(UserEntity userEntity) {
if (userRepository.findByUsername(userEntity.getUsername()).isPresent()) {
return Optional.empty();
}
return Optional.of(userRepository.save(userEntity));
}
}
UserController. java
package com.mse.wcp.forum.controllers;
import com.mse.wcp.forum.dtos.UserDTO;
import com.mse.wcp.forum.mappers.UserMapper;
import com.mse.wcp.forum.persistence.entities.UserEntity;
import com.mse.wcp.forum.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
/**
* Responsible for user management.
*/
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private UserMapper mapper;
/**
* Gets all users.
*
* @return the users.
*/
@GetMapping
public ResponseEntity<List<UserDTO>> getAll() {
return ResponseEntity.ok(mapper.toUserDTOs(userService.getAll()));
}
/**
* Gets user by id.
*
* @param id the id.
* @return the user.
*/
@GetMapping("/{id}")
public ResponseEntity<UserDTO> get(@PathVariable("id") Long id) {
Optional<UserEntity> userEntity = userService.get(id);
return userEntity.map(entity -> ResponseEntity.ok(mapper.toUserDTO(entity))).orElseGet(() -> ResponseEntity.notFound().build());
}
/**
* Creates a new user.
*
* @param userDTO the userDto.
* @return the userDto.
*/
@PostMapping
public ResponseEntity<UserDTO> create(@RequestBody UserDTO userDTO) {
Optional<UserEntity> userEntity = userService.create(mapper.toUserEntity(userDTO));
return userEntity.map(entity -> ResponseEntity.ok(mapper.toUserDTO(entity))).orElseGet(() -> ResponseEntity.status(HttpStatus.CONFLICT).build());
}
}
UserEntity. java
package com.mse.wcp.forum.persistence.entities;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.util.Date;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity(name = "users")
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String username;
private String password;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
private String role;
@CreationTimestamp
@Column(name = "created_at")
private Date createdAt;
@UpdateTimestamp
@Column(name = "modified_at")
private Date modifiedAt;
}
UserDTO. java
package com.mse.wcp.forum.dtos;
import lombok.Data;
@Data
public class UserDTO {
private String username;
private String password;
private String firstName;
private String lastName;
private String role;
}
pom. xml
<?xml version="1.0" encoding="UTF-8"?>
<project 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mse.wcp</groupId>
<artifactId>forum</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>forum</name>
<description>Forum</description>
<properties>
<java.version>1.8</java.version>
<org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>