gpt4 book ai didi

spring-mvc - 让mockMVC 测试过滤器的init 例程需要什么?

转载 作者:行者123 更新时间:2023-12-03 07:01:41 24 4
gpt4 key购买 nike

我已经实现了以下 CORS 过滤器,该过滤器在服务器上执行代码时起作用:

/*
* Copyright 2013 BrandsEye (http://www.brandseye.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.energyos.espi.datacustodian.web.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.stereotype.Component;

/**
* Adds CORS headers to requests to enable cross-domain access.
*/

@Component
public class CORSFilter implements Filter {

private final Log logger = LogFactory.getLog(getClass());
private final Map<String, String> optionsHeaders = new LinkedHashMap<String, String>();

private Pattern allowOriginRegex;
private String allowOrigin;
private String exposeHeaders;

public void init(FilterConfig cfg) throws ServletException {
String regex = cfg.getInitParameter("allow.origin.regex");
if (regex != null) {
allowOriginRegex = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
} else {
optionsHeaders.put("Access-Control-Allow-Origin", "*");
}

optionsHeaders.put("Access-Control-Allow-Headers", "Origin, Authorization, Accept, Content-Type");
optionsHeaders.put("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
optionsHeaders.put("Access-Control-Max-Age", "1800");
for (Enumeration<String> i = cfg.getInitParameterNames(); i.hasMoreElements(); ) {
String name = i.nextElement();
if (name.startsWith("header:")) {
optionsHeaders.put(name.substring(7), cfg.getInitParameter(name));
}
}

//maintained for backward compatibility on how to set allowOrigin if not
//using a regex
allowOrigin = optionsHeaders.get("Access-Control-Allow-Origin");
//since all methods now go through checkOrigin() to apply the Access-Control-Allow-Origin
//header, and that header should have a single value of the requesting Origin since
//Access-Control-Allow-Credentials is always true, we remove it from the options headers
optionsHeaders.remove("Access-Control-Allow-Origin");

exposeHeaders = cfg.getInitParameter("expose.headers");
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {

if (logger.isDebugEnabled()) {
logger.debug("CORSFilter processing: Checking for Cross Origin pre-flight OPTIONS message");
}

if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
if ("OPTIONS".equals(req.getMethod())) {
allowOrigin = "*"; //%%%%% Test force of allowOrigin
if (checkOrigin(req, resp)) {
for (Map.Entry<String, String> e : optionsHeaders.entrySet()) {
resp.addHeader(e.getKey(), e.getValue());
}

// We need to return here since we don't want the chain to further process
// a preflight request since this can lead to unexpected processing of the preflighted
// request or a 40x - Response Code
return;

}
} else if (checkOrigin(req, resp)) {
if (exposeHeaders != null) {
resp.addHeader("Access-Control-Expose-Headers", exposeHeaders);
}
}
}
filterChain.doFilter(request, response);
}

private boolean checkOrigin(HttpServletRequest req, HttpServletResponse resp) {
String origin = req.getHeader("Origin");
if (origin == null) {
//no origin; per W3C specification, terminate further processing for both pre-flight and actual requests
return false;
}

boolean matches = false;
//check if using regex to match origin
if (allowOriginRegex != null) {
matches = allowOriginRegex.matcher(origin).matches();
} else if (allowOrigin != null) {
matches = allowOrigin.equals("*") || allowOrigin.equals(origin);
}

if (matches) {

// Activate next two lines and comment out third line if Credential Support is required
// resp.addHeader("Access-Control-Allow-Origin", origin);
// resp.addHeader("Access-Control-Allow-Credentials", "true");
resp.addHeader("Access-Control-Allow-Origin", "*");
return true;
} else {
return false;
}
}

public void destroy() {
}
}

以下 JUnit 测试使用 mockMVC 但失败,因为 CORSFilter 的“init”逻辑未执行(通过在 JUnit 测试中设置断点来证明):

package org.energyos.espi.datacustodian.integration.web.filters;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.FilterConfig;

import org.energyos.espi.datacustodian.web.filter.CORSFilter;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("/spring/test-context.xml")
@Profile("test")
public class CORSFilterTests {

private final Log logger = LogFactory.getLog(getClass());

@Autowired
private CORSFilter filter;

@Autowired
private WebApplicationContext wac;

private MockMvc mockMvc;

@Before
public void setup() {
this.mockMvc = webAppContextSetup(this.wac)
.addFilters(filter).build();
}

@Test
public void optionsResponse_hasCorrectFilters() throws Exception {

RequestBuilder requestBuilder = MockMvcRequestBuilders.options("/DataCustodian/oauth/token")
.header("Origin", "foobar")
.header("Access-Control-Allow-Origin", "*");

MvcResult result = mockMvc.perform(requestBuilder)
.andExpect(header().string("Access-Control-Allow-Origin", is("*")))
.andExpect(header().string("Access-Control-Allow-Methods", is("GET, POST, PUT, DELETE, OPTIONS")))
.andExpect(header().string("Access-Control-Allow-Headers", is("origin, authorization, accept, content-type")))
.andExpect(header().string("Access-Control-Max-Age", is("1800")))
.andReturn();
}
}
}

我已经查看了互联网上的可用 Material ,这似乎暗示了“.addfilter(filter)。mockMVC @Before 部分的元素应该执行 CORSFilter init 例程。但是,这显然没有发生。

任何建议或建议将不胜感激,因为我真的很难理解如何使用mockMVC功能测试“init”例程。

最佳答案

Spring MVC 测试套件并不是为了测试容器配置,而是为了测试您的 MVC(@Controller 和其他映射)配置。 Filter#init(ServletConfig) 是容器管理的方法。

如果你确实需要测试它,你也可以模拟它

@Before
public void setup() {
filter.init(someMockFilterConfig); // using a mock that you construct with init params and all
this.mockMvc = webAppContextSetup(this.wac)
.addFilters(filter).build();
}

关于spring-mvc - 让mockMVC 测试过滤器的init 例程需要什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20819130/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com