我正在尝试用POST方法测试控制器。我不敢相信这怎么可能,当我在测试方法中设置内容类型时,它没有设置。有人能帮助我吗?我失去了我的头脑,我完全沮丧。我还没有找到这个问题的答案。一些类似于我的,但解决方案没有工作。
这是我的代码:
储存库:
import com.sklepinternetowybackend.model.dao.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, String> {
Optional<User> findByEmail(String email);
boolean existsByEmail(String email);
}
服务项目:
import com.sklepinternetowybackend.exceptions.EmailException;
import com.sklepinternetowybackend.exceptions.IdNotFoundException;
import com.sklepinternetowybackend.exceptions.NoUsersFoundException;
import com.sklepinternetowybackend.mapper.UserMapper;
import com.sklepinternetowybackend.model.dao.User;
import com.sklepinternetowybackend.model.dto.UserRequestDto;
import com.sklepinternetowybackend.model.dto.UserResponseDto;
import com.sklepinternetowybackend.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
private final PasswordEncoder encoder;
public UserResponseDto createUser(UserRequestDto userRequestDto) {
boolean userEmailExists = userRepository.existsByEmail(userRequestDto.getEmail());
EmailException exception = new EmailException(userRequestDto.getEmail());
if(userEmailExists) {
throw exception;
}
User user = userMapper.requestDtoToDao(userRequestDto);
user.setPassword(encoder.encode(userRequestDto.getPassword()));
userRepository.save(user);
return userMapper.requestToResponse(userRequestDto);
}
控制器:
import com.sklepinternetowybackend.exceptions.NoUsersFoundException;
import com.sklepinternetowybackend.model.dto.UserRequestDto;
import com.sklepinternetowybackend.model.dto.UserResponseDto;
import com.sklepinternetowybackend.service.UserServiceImpl;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import java.util.List;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/api/user", produces = APPLICATION_JSON_VALUE)
@Validated
public class UserController {
private final UserServiceImpl service;
@PostMapping(consumes = APPLICATION_JSON_VALUE, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseStatus(HttpStatus.CREATED)
@ApiOperation(value = "Create new user", notes = "Method allows to create new user and save it to database")
public UserResponseDto createUser(@Valid @RequestBody UserRequestDto request) {
return service.createUser(request);
}
最后是我的测试方法:
import com.sklepinternetowybackend.model.dto.UserRequestDto;
import com.sklepinternetowybackend.model.dto.UserResponseDto;
import com.sklepinternetowybackend.service.UserServiceImpl;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.UUID;
import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.reset;
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.*;
@ExtendWith(MockitoExtension.class)
public class UserControllerTestAnotherWay {
@Mock
UserServiceImpl service;
@InjectMocks
UserController controller;
MockMvc mockMvc;
UserResponseDto userResponseDto;
UserRequestDto userRequestDto;
public static final String EMAIL = "janusz.nosacz@gmail.com";
public static final String FIRST_NAME = "Janusz";
public static final String LAST_NAME = "Nosacz";
public static final String PASSWORD = "Password666!";
public static final String APPLICATION_JSON = "application/json";
public static final String API_USER = "/api/user";
public static final String FIRST_NAME_PROPERTY = "firstName";
public static final String LAST_NAME_PROPERTY = "lastName";
public static final String PASSWORD_PROPERTY = "password";
public static final String EMAIL_PROPERTY = "email";
@BeforeEach
void setup() {
userResponseDto = UserResponseDto.builder()
.firstName(FIRST_NAME)
.lastName(LAST_NAME)
.email(EMAIL)
.build();
userRequestDto = UserRequestDto.builder()
.firstName(FIRST_NAME)
.lastName(LAST_NAME)
.email(EMAIL)
.password(UUID.randomUUID().toString())
.build();
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@AfterEach
void tearDown() {
reset(service);
}
@Test
@DisplayName("Test for adding user to db and return proper response body")
void shouldAddUserAndProduceProperResponseBody() throws Exception {
given(service.findUserByEmail(anyString())).willReturn(userResponseDto);
mockMvc.perform(post("/api/user").contentType(MediaType.APPLICATION_JSON).characterEncoding("utf-8")
.param(FIRST_NAME_PROPERTY, userRequestDto.getFirstName())
.param(LAST_NAME_PROPERTY, userRequestDto.getLastName())
.param(EMAIL_PROPERTY, userRequestDto.getEmail())
.param(PASSWORD_PROPERTY, userRequestDto.getPassword()))
.andDo(print())
.andExpect(content().contentType(APPLICATION_JSON));
}
}
和堆栈跟踪:
12:10:59.394 [main] DEBUG org.jboss.logging - Logging Provider: org.jboss.logging.Log4j2LoggerProvider
12:10:59.396 [main] INFO org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 6.2.3.Final
12:10:59.410 [main] DEBUG org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator - Loaded expression factory via original TCCL
12:10:59.411 [main] DEBUG org.hibernate.validator.internal.engine.AbstractConfigurationImpl - Setting custom MessageInterpolator of type org.springframework.validation.beanvalidation.LocaleContextMessageInterpolator
12:10:59.411 [main] DEBUG org.hibernate.validator.internal.engine.AbstractConfigurationImpl - Setting custom ParameterNameProvider of type org.springframework.validation.beanvalidation.LocalValidatorFactoryBean$1
12:10:59.414 [main] DEBUG org.hibernate.validator.internal.xml.config.ValidationXmlParser - Trying to load META-INF/validation.xml for XML based Validator configuration.
12:10:59.415 [main] DEBUG org.hibernate.validator.internal.xml.config.ResourceLoaderHelper - Trying to load META-INF/validation.xml via TCCL
12:10:59.416 [main] DEBUG org.hibernate.validator.internal.xml.config.ResourceLoaderHelper - Trying to load META-INF/validation.xml via Hibernate Validator's class loader
12:10:59.416 [main] DEBUG org.hibernate.validator.internal.xml.config.ValidationXmlParser - No META-INF/validation.xml found. Using annotation based configuration only.
12:10:59.421 [main] DEBUG org.hibernate.validator.internal.engine.resolver.TraversableResolvers - Found javax.persistence.Persistence on classpath containing 'getPersistenceUtil'. Assuming JPA 2 environment. Trying to instantiate JPA aware TraversableResolver
12:10:59.423 [main] DEBUG org.hibernate.validator.internal.engine.resolver.TraversableResolvers - Instantiated JPA aware TraversableResolver of type org.hibernate.validator.internal.engine.resolver.JPATraversableResolver.
12:10:59.484 [main] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000252: Using org.hibernate.validator.internal.engine.DefaultPropertyNodeNameProvider as property node name provider.
12:10:59.489 [main] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.springframework.validation.beanvalidation.LocaleContextMessageInterpolator as ValidatorFactory-scoped message interpolator.
12:10:59.489 [main] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.hibernate.validator.internal.engine.resolver.JPATraversableResolver as ValidatorFactory-scoped traversable resolver.
12:10:59.490 [main] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.hibernate.validator.internal.util.ExecutableParameterNameProvider as ValidatorFactory-scoped parameter name provider.
12:10:59.490 [main] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.hibernate.validator.internal.engine.DefaultClockProvider as ValidatorFactory-scoped clock provider.
12:10:59.490 [main] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory as ValidatorFactory-scoped script evaluator factory.
12:10:59.594 [main] DEBUG _org.springframework.web.servlet.HandlerMapping.Mappings -
c.s.c.UserController:
{GET [/api/user], params [email], produces [application/json]}: findUserByEmail(String)
{POST [/api/user], consumes [application/json], produces [application/json]}: createUser(UserRequestDto)
{GET [/api/user/{id}], produces [application/json]}: findUserById(String)
{GET [/api/user/all], produces [application/json]}: showAllUsers()
{DELETE [/api/user/{id}], produces [application/json]}: deleteUserById(String)
{PUT [/api/user/{id}], produces [application/json]}: updateUser(String,UserRequestDto)
12:10:59.602 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - 6 mappings in org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
12:10:59.804 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - ControllerAdvice beans: 0 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 1 ResponseBodyAdvice
12:10:59.829 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - ControllerAdvice beans: 0 @ExceptionHandler, 1 ResponseBodyAdvice
12:10:59.846 [main] INFO org.springframework.mock.web.MockServletContext - Initializing Spring TestDispatcherServlet ''
12:10:59.846 [main] INFO org.springframework.test.web.servlet.TestDispatcherServlet - Initializing Servlet ''
12:10:59.848 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Detected AcceptHeaderLocaleResolver
12:10:59.848 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Detected FixedThemeResolver
12:10:59.848 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@4d95a72e
12:10:59.848 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Detected org.springframework.web.servlet.support.SessionFlashMapManager@28da7d11
12:10:59.849 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
12:10:59.849 [main] INFO org.springframework.test.web.servlet.TestDispatcherServlet - Completed initialization in 3 ms
12:10:59.886 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - POST "/api/user", parameters={masked}
12:10:59.890 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.sklepinternetowybackend.controller.UserController#createUser(UserRequestDto)
12:10:59.947 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor - Read "application/json;charset=utf-8" to []
12:10:59.951 [main] WARN org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.sklepinternetowybackend.model.dto.UserResponseDto com.sklepinternetowybackend.controller.UserController.createUser(com.sklepinternetowybackend.model.dto.UserRequestDto)]
12:10:59.951 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Completed 400 BAD_REQUEST
MockHttpServletRequest:
HTTP Method = POST
Request URI = /api/user
Parameters = {firstName=[Janusz], lastName=[Nosacz], email=[janusz.nosacz@gmail.com], password=[9f27dde8-3a9a-4cc4-a1dc-40d8598c1629]}
Headers = [Content-Type:"application/json;charset=utf-8"]
Body = null
Session Attrs = {}
Handler:
Type = com.sklepinternetowybackend.controller.UserController
Method = com.sklepinternetowybackend.controller.UserController#createUser(UserRequestDto)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.http.converter.HttpMessageNotReadableException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 400
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: Content type not set
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:37)
at org.springframework.test.util.AssertionErrors.assertTrue(AssertionErrors.java:70)
at org.springframework.test.util.AssertionErrors.assertNotNull(AssertionErrors.java:106)
at org.springframework.test.web.servlet.result.ContentResultMatchers.lambda$contentType$0(ContentResultMatchers.java:85)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:212)
at com.sklepinternetowybackend.controller.UserControllerTestAnotherWay.shouldAddUserAndProduceProperResponseBody(UserControllerTestAnotherWay.java:103)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
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:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
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$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Process finished with exit code 255
2条答案
按热度按时间rvpgvaaj1#
您遗漏了一点。您的终结点需要类型为
UserRequestDto
的主体:但您所做的是将用户属性作为URL参数发送:
查看此答案,了解如何正确发布正文:Testing Spring's @RequestBody using Spring MockMVC
vhipe2zx2#
您应该在Controller中为每个参数使用@RequestParam(更改源代码),或者在test中用.content(“jsonContent”)替换参数
}