在 Spring boot 中为 Filter (OncePerRequestFilter) 编写单元测试
Posted
技术标签:
【中文标题】在 Spring boot 中为 Filter (OncePerRequestFilter) 编写单元测试【英文标题】:Writing unit test for Filter (OncePerRequestFilter) in Spring boot 【发布时间】:2019-11-19 02:41:37 【问题描述】:我有扩展 OncePerRequestFilter 的过滤器类。此过滤器用于捕获审计数据,然后传递给异步方法以持久保存在 db 中。 我需要为整个场景编写测试用例。如何做到这一点?我在 Junit 方面没有任何出色的专业知识。
public class AuditFilter extends OncePerRequestFilter
private static final Logger LOGGER = LoggerFactory.getLogger(AuditFilter.class);
private AuditLogManager auditLogManager;
private String auditMode;
private List<String> urlPatterns;
/**
* @param auditLogManager - processes the audit logs.
* @param auditMode - modes of auditing (OFF,BASIC,DETAILED).
* @param urlPatterns - the URL patterns for which auditing to be done.
*/
public AuditFilter(final AuditLogManager auditLogManager, final String auditMode,
final List<String> urlPatterns)
this.auditLogManager = auditLogManager;
this.auditMode = auditMode;
this.urlPatterns = urlPatterns;
@Override()
protected void doFilterInternal(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain filterChain)
throws ServletException, IOException
//capture audit data from request
try
filterChain.doFilter(wrappedRequest, wrappedResponse);
finally
//capture audit data from response
// Executing asynchronous call. auditLogManager uses @Async annotation. Need i=integration test for auditLogManager code also
auditLogManager.log(auditInfo, auditMode);
我需要在 maven 构建期间对 AuditFilter 和 AuditLogManager(具有异步方法的类)执行的每个操作进行单元测试。
【问题讨论】:
您的问题令人困惑。你想要单元测试还是集成测试?两者完全不同。单元测试是针对原始 Java 源代码执行的(在部署之前)。针对正在运行的服务器执行集成测试(部署后)。对于单元测试,您需要某种模拟库(例如 Mockito)来模拟与真实运行的服务器上相同的条件(因此这很可疑)。对于集成测试,您需要一个复杂的集成测试框架(例如 Arquillian+Selenium),但您没有指定当前使用的是哪一个。 抱歉没有正确提及。我只需要一个单元测试。这些测试用例应该在我构建项目时执行。就是这样。 在构建过程中也会执行集成测试。 我想我需要做如下。首先,我需要测试我的 OncePerRequestFilter。而从过滤器中调用的异步代码,我需要单独测试。是吗? 【参考方案1】:这可能是迟到的回应。但是可以使用另一种方法。
对于当前的 spring 2.5.5,一种选择是使用 RestTemplate 方法
// use below annotation at class level
// the WebEnvironment with Random_port, this is required for test case
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Test
void postTest()
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String bodyContent = "\"appAPI\":\"<SOME-API-CODE-or-USER-NAME>\"";
HttpEntity<String> requestEntity = new HttpEntity<>(bodyContent, headers);
//END POINT exposed in myapp, which will be used to provide the token.
String token = restTemplate
.postForObject("/myapp/authenticate",requestEntity, String.class);
ObjectMapper mapper = new ObjectMapper();
JsonNode root;
try
root = mapper.readTree(token);
JsonNode tokenVal = root.path("jwtToken");
System.out.println("TKN: "+tokenVal.asText());
Assert.isTrue(tokenVal.asText()!=null, "Token received successfully");
catch (JsonProcessingException e)
Assert.isTrue(false,"Exception occurred: "+e.getMessage());
就我而言,我有一个用于 jwt 响应的 Java POJO,因此来自 POST 端点的响应是一个 POJO,因此使用 ObjectMapper 进行解析和验证。
【讨论】:
以上是关于在 Spring boot 中为 Filter (OncePerRequestFilter) 编写单元测试的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 中为 Spring LDAP 身份验证设置覆盖 BindAuthenticator handleBindException
无法在 Spring Boot 中为 Hikari 设置 keepAlive Time 配置
Spring Boot参考教程Spring Boot配置Servlet,Filter,Listener,Interceptor