gpt4 book ai didi

java - 测试 Spring MultipartHttpServletRequest

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:48:51 26 4
gpt4 key购买 nike

尝试测试我们用于多个文件上传的 spring Controller 。这是 Controller :

@RequestMapping("/vocabularys")
@Controller
public class VocabularyController {
...

我要测试的 Action :

@RequestMapping(value = "/import", method = {RequestMethod.PUT, RequestMethod.POST})
@ResponseBody
@CacheEvict(value="vocabulary", allEntries=true)
public Object importVocabulary(MultipartHttpServletRequest request, HttpServletResponse response) {
...

我在 webmvc-config.xml 中的解析器:

<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"/>

代码工作得很好。我在尝试对此进行单元/集成测试时遇到了问题。

这是我的测试尝试:

public class VocabularyControllerTest extends BaseControllerTest {

static final private String AdminUsername = "administrator";

@Test
public void shouldBeAbleToUploadAFile() throws Exception {
createTestWorkspace();
login(AdminUsername, "*");

MockMultipartFile file = new MockMultipartFile("test_vocab.xml", new FileInputStream("src/test/files/acme_vocabulary.xml"));
MockMultipartHttpServletRequestBuilder mockMultipartHttpServletRequestBuilder = (MockMultipartHttpServletRequestBuilder) fileUpload("/vocabularys/import").accept(MediaType.ALL).session(httpSession);
mockMultipartHttpServletRequestBuilder.file(file);
mockMultipartHttpServletRequestBuilder.content("whatever");

ResultActions resultActions = mockMvc.perform(mockMultipartHttpServletRequestBuilder);

resultActions.andExpect(status().isFound());
}
}

忽略 createWorkspace()login() 之类的东西 - 它们用于通过一些安全过滤器。

BaseControllerTest 的相关部分:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextHierarchy({
@ContextConfiguration(locations = {
"file:src/test/resources/META-INF/spring/applicationContext.xml",
"file:src/test/resources/META-INF/spring/applicationContext-security.xml",
"file:src/main/resources/META-INF/spring/applicationContext-database.xml",
"file:src/main/resources/META-INF/spring/applicationContext-activiti.xml",
"file:src/main/resources/META-INF/spring/applicationContext-cache.xml",
"file:src/main/resources/META-INF/spring/applicationContext-jms.xml",
"file:src/main/resources/META-INF/spring/applicationContext-mail.xml",
"file:src/main/resources/META-INF/spring/applicationContext-mongo.xml"}),
@ContextConfiguration(locations = {
"file:src/main/webapp/WEB-INF/spring/webmvc-config.xml",
"file:src/test/webapp/WEB-INF/spring/applicationContext-filters.xml"})
})
@Transactional
public class BaseControllerTest extends BaseTest {

@Autowired
WebApplicationContext wac;
@Autowired
MockHttpSession httpSession;
@Autowired
MockServletContext servletContext;
@Autowired
OpenEntityManagerInViewFilter openEntityManagerInViewFilter;
@Autowired
HiddenHttpMethodFilter hiddenHttpMethodFilter;
@Autowired
CharacterEncodingFilter characterEncodingFilter;
@Autowired
SessionFilter sessionFilter;
@Autowired
WorkflowAsSessionFilter workflowAsSessionFilter;
@Autowired
FilterChainProxy springSecurityFilterChain;
@Autowired
RequestFilter requestFilter;
MockMvc mockMvc;

protected static final String TestFileDir = "src/test/files/";

@Before
public void setUp() throws Exception {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
.addFilter(openEntityManagerInViewFilter, "/*")
.addFilter(hiddenHttpMethodFilter, "/*")
.addFilter(characterEncodingFilter, "/*")
.addFilter(sessionFilter, "/*")
.addFilter(workflowAsSessionFilter, "/*")
.addFilter(springSecurityFilterChain, "/*")
.addFilter(requestFilter, "/*")
.build();

servletContext.setContextPath("/");

Session session = Session.findBySessionId(httpSession.getId());
if (session == null) {
session = new Session();
session.setJsessionid(httpSession.getId());
session.persist();
}
}
...

问题是,当我尝试对此进行调试时,mockMvc 对象上的perform 操作永远不会触发我的 Controller 方法。我认为通过我们的安全过滤器是一个问题(这就是为什么我拥有所有 login 和东西)但是我测试了词汇 Controller 中的其他操作并且我能够很好地击中它们。

想法?想法?有什么建议吗?

最佳答案

好的,找到问题了。

Spring 的 MockMultipartHttpServletRequestBuilder 最终返回一个 MockHttpMultipartServletRequest 对象。

然而,浏览器所做的是发布一个多部分编码的请求,然后由 XML 中定义的 CommonsMultipartResolver bean 获取并解析该请求。

然而在测试中,由于我们已经发布了一个MockHttpMultipartServletRequest,我们不希望解析器解析它,所以我们要做的就是拥有一个解析器不启动的配置文件中。

然而,我们选择做的是最终构建一个具有多部分编码的 MockHttpServletRequest 并将其放入 Spring 过滤器,以便我们还可以集成测试解析器。

不幸的是,我在 Spring 测试库中没有看到任何支持/帮助程序,它允许您使用 MockHttpServletRequestaddPart()到它,或类似的效果=> 手写浏览器仿真功能:(

关于java - 测试 Spring MultipartHttpServletRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19140133/

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