如何避免在 Spring 引导集成测试中使用拦截器
How to avoid using an interceptor in Spring boot integration tests
我在测试 REST 请求时遇到问题。在我的应用程序中,我有一个拦截器,它在允许请求之前检查令牌有效性。但是对于我的集成测试,我想绕过检查。换句话说,我想分流拦截器或将其模拟为始终 return true.
这是我的简化代码:
@Component
public class RequestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String token = request.getHeader("Authorization");
if (token != null) {
return true;
} else {
return false;
}
}
}
@Configuration
public class RequestInterceptorAppConfig implements WebMvcConfigurer {
@Autowired
RequestInterceptor requestInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestInterceptor).addPathPatterns("/**");
}
}
和测试:
@SpringBootTest(classes = AppjhipsterApp.class)
@AutoConfigureMockMvc
@WithMockUser
public class DocumentResourceIT {
@Autowired
private DocumentRepository documentRepository;
@Autowired
private MockMvc restDocumentMockMvc;
private Document document;
public static Document createEntity() {
Document document = new Document()
.nom(DEFAULT_NOM)
.emplacement(DEFAULT_EMPLACEMENT)
.typeDocument(DEFAULT_TYPE_DOCUMENT);
return document;
}
@BeforeEach
public void initTest() {
document = createEntity();
}
@Test
@Transactional
public void createDocument() throws Exception {
int databaseSizeBeforeCreate = documentRepository.findAll().size();
// Create the Document
restDocumentMockMvc.perform(post("/api/documents")
.contentType(MediaType.APPLICATION_JSON)
.content(TestUtil.convertObjectToJsonBytes(document)))
.andExpect(status().isCreated());
}
}
当 运行 测试时,它总是通过拦截器并被拒绝,因为我没有有效的令牌。我这里的代码是简化的,我无法获得有效的测试令牌,所以我真的需要跳过拦截器。
感谢您的帮助
我会通过在拦截器上使用配置文件来解决这个问题。在您的测试中,您没有 运行 配置文件(未注入 bean)。在您的作品或您需要的任何环境中,您 运行 使用新的配置文件。
当然你需要稍微改变一下用法。这应该有效:
@Configuration
public class RequestInterceptorAppConfig implements WebMvcConfigurer {
@Autowired
Collection<RequestInterceptor> requestInterceptors;
@Override
public void addInterceptors(InterceptorRegistry registry) {
requestInterceptors.forEach(interceptor -> registry.addInterceptor(interceptor).addPathPatterns("/**");
}
}
模拟它(在集成测试中):
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
// non-static imports
@SpringBootTest
// other stuff
class IntegrationTest {
@MockBean
RequestInterceptor interceptor;
// other stuff
@BeforeEach
void initTest() {
when(interceptor.preHandle(any(), any(), any())).thenReturn(true);
// other stuff
}
// tests
}
@BeforeEach 和@SpringBootTest 的作用,你懂的; Mockito 的 any() 只是说“不管争论”;对于@MockBean 和Mockito 的when-then,Javadoc 已经足够好了,我觉得不需要添加信息。
我在测试 REST 请求时遇到问题。在我的应用程序中,我有一个拦截器,它在允许请求之前检查令牌有效性。但是对于我的集成测试,我想绕过检查。换句话说,我想分流拦截器或将其模拟为始终 return true.
这是我的简化代码:
@Component
public class RequestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String token = request.getHeader("Authorization");
if (token != null) {
return true;
} else {
return false;
}
}
}
@Configuration
public class RequestInterceptorAppConfig implements WebMvcConfigurer {
@Autowired
RequestInterceptor requestInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestInterceptor).addPathPatterns("/**");
}
}
和测试:
@SpringBootTest(classes = AppjhipsterApp.class)
@AutoConfigureMockMvc
@WithMockUser
public class DocumentResourceIT {
@Autowired
private DocumentRepository documentRepository;
@Autowired
private MockMvc restDocumentMockMvc;
private Document document;
public static Document createEntity() {
Document document = new Document()
.nom(DEFAULT_NOM)
.emplacement(DEFAULT_EMPLACEMENT)
.typeDocument(DEFAULT_TYPE_DOCUMENT);
return document;
}
@BeforeEach
public void initTest() {
document = createEntity();
}
@Test
@Transactional
public void createDocument() throws Exception {
int databaseSizeBeforeCreate = documentRepository.findAll().size();
// Create the Document
restDocumentMockMvc.perform(post("/api/documents")
.contentType(MediaType.APPLICATION_JSON)
.content(TestUtil.convertObjectToJsonBytes(document)))
.andExpect(status().isCreated());
}
}
当 运行 测试时,它总是通过拦截器并被拒绝,因为我没有有效的令牌。我这里的代码是简化的,我无法获得有效的测试令牌,所以我真的需要跳过拦截器。
感谢您的帮助
我会通过在拦截器上使用配置文件来解决这个问题。在您的测试中,您没有 运行 配置文件(未注入 bean)。在您的作品或您需要的任何环境中,您 运行 使用新的配置文件。
当然你需要稍微改变一下用法。这应该有效:
@Configuration
public class RequestInterceptorAppConfig implements WebMvcConfigurer {
@Autowired
Collection<RequestInterceptor> requestInterceptors;
@Override
public void addInterceptors(InterceptorRegistry registry) {
requestInterceptors.forEach(interceptor -> registry.addInterceptor(interceptor).addPathPatterns("/**");
}
}
模拟它(在集成测试中):
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
// non-static imports
@SpringBootTest
// other stuff
class IntegrationTest {
@MockBean
RequestInterceptor interceptor;
// other stuff
@BeforeEach
void initTest() {
when(interceptor.preHandle(any(), any(), any())).thenReturn(true);
// other stuff
}
// tests
}
@BeforeEach 和@SpringBootTest 的作用,你懂的; Mockito 的 any() 只是说“不管争论”;对于@MockBean 和Mockito 的when-then,Javadoc 已经足够好了,我觉得不需要添加信息。