我正在尝试测试(通过 Spring 测试(mvc))一个使用的控制器servletRequest.getParts()
到目前为止我所读到的就是MockMvcRequestBuilders.fileUpload().file()解决方案。但是我无法让它发挥作用。我编写了以下失败的测试
MockMultipartHttpServletRequestBuilder builder = MockMvcRequestBuilders.fileUpload("/foo")
.file(new MockMultipartFile("file", new byte[] { 1, 2, 3, 4 }));
MockHttpServletRequest rq = builder.buildRequest(null);
Assert.assertEquals(1, rq.getParts().size()); // result 0
Run Code Online (Sandbox Code Playgroud)
我浏览了 spring 代码,并且调用file(...)添加了一个元素,List<MockMultipartFile>当getParts()从另一个列表获取其元素时(Map<String, Part> parts)
必须有另一种方法来做到这一点......
编辑1
我用来测试控制器的代码是:
ResultActions result = mockMvc.perform(
MockMvcRequestBuilders.fileUpload(new URI("/url")).file("param", "expected".getBytes()))
Run Code Online (Sandbox Code Playgroud) 我正在尝试在spring-boot 2.x项目中使用Junit 5来测试Controller.
以下工作正常
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@WebMvcTest(TypesController.class)
@RunWith(SpringRunner.class)
public class TypesControllerTest {
@Autowired
WebApplicationContext wac;
@Test
public void testTypes() throws Exception {
webAppContextSetup(wac).build().perform(get("/types").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()).andExpect(content().contentType("application/json;charset=UTF-8"));
}
@EnableWebMvc
@Configuration
@ComponentScan(basePackageClasses = { TypesController.class })
static class Config {
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将其更改为使用SpringExtention,
..
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.junit.jupiter.api.extension.ExtendWith;
..
@ExtendWith(SpringExtension.class)
@WebMvcTest(TypesController.class)
public class TypesControllerTest …Run Code Online (Sandbox Code Playgroud) 当我使用类似于此的WebApplicationContext使用spring MVC 3.2.3为restful-webservice测试创建MockMvc时:
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
然后当我运行我的测试时,它将失败并返回代码404并且我的日志说明了
Did not find handler method for [my/path]
Run Code Online (Sandbox Code Playgroud)
但如果我改变这种方式
public class MyWebTests {
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
然后我的测试运行良好,没有任何错误.
我知道的唯一区别是,如果我使用WebApplicationContext创建MockMvc然后它将加载我的Spring Confuguration,而如果我使用Controller然后它不会.
在我的情况下,什么可能导致该错误(没有找到处理程序方法...)?
编辑我的测试课程
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:restful-test-context.xml")
@WebAppConfiguration
public class TestSourceController {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
private ObjectMapper mapper;
@Autowired
DeviceDAO deviceDAO;
@AfterClass
public static void …Run Code Online (Sandbox Code Playgroud) 我已经浏览了https://github.com/spring-projects/spring-boot/issues/424但我的项目结构在 /templates 目录中包含 .html 文件,如下所示
.
|-- java
| `-- com
| `-- projectx
| |-- config
| | |-- Application.java
| | `-- WebXmlInitialiser.java
| |-- controller
| | `-- CustomerQuickRegisterController.java
| |-- domain
| | `-- Email.java
| `-- services
| |-- CustomerQuickRegisterDataFixtures.java
| |-- CustomerQuickRegisterHandler.java
| `-- CustomerQuickRegisterService.java
`-- resources
|-- application.properties
`-- templates
|-- emailForm.html
`-- result.html
Run Code Online (Sandbox Code Playgroud)
但是仍然在使用以下测试进行测试时
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
@ActiveProfiles("Test")
public class CustomerQuickRegisterControllerIntergrationTest {
@Autowired
private WebApplicationContext wac;
MockMvc …Run Code Online (Sandbox Code Playgroud) 我有一个像这样的控制器:
@RestController
@RequestMapping('/v1/document')
class DocumentV1Controller {
@PutMapping
HttpEntity<Document> newdoc(
@RequestHeader Map<String, String> headers, @RequestParam('document') MultipartFile multipartFile) {
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用Spring MVC Test和Spock进行测试,但我无法弄清楚如何构建一个MockMultipartHttpServletRequestBuilder将HttpMethod从POST更改为PUT请求.
这是Spock规范:
class DocumentV1ControllerSpec extends BaseControllerSpec {
Should 'test and document good request on /v1/document endpoint'() {
given:
File file = new File('./src/test/resources/demoC.csv')
MockMultipartFile multipartFile = new MockMultipartFile('file',file.getBytes())
when:
ResultActions result = mockMvc.perform(fileUpload('/v1/document')
.file(multipartFile))
then:
result.andExpect(status().isCreated())
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是这样的:
java.lang.AssertionError: Status expected:<201> but was:<405>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
at gus.rest.api.v1.DocumentV1ControllerSpec.test and document good …Run Code Online (Sandbox Code Playgroud) 这是我的webConfig
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个/health端点,它返回一些健康数据,它工作正常.
这是junit测试
@Test
public void corsTest() {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ORIGIN, "http://localhost:9000");
HttpEntity<?> requestEntity = new HttpEntity(headers);
ResponseEntity<Status> entity = this.restTemplate.exchange("/health", HttpMethod.GET, requestEntity, Status.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals("http://localhost:9000", entity.getHeaders().getAccessControlAllowOrigin()); //6
Status health = entity.getBody();
assertThat(health.getAppName()).isEqualTo(appName);
}
Run Code Online (Sandbox Code Playgroud)
测试在第6行失败.如果注释掉该行,则测试通过.通过调试器,我发现它entity.getHeaders().getAccessControlAllowOrigin()是null.我使用这个示例应用程序作为参考,它工作正常.但对于我的申请,它失败了.
当我使用javascript调用/ health api时,我可以看到cors工作.如果我注释掉webConfig类,我会在javascript中收到错误.在javascript上调试更多信息表明,未设置cors响应标头,但启用webconfig时请求成功提供.
所以绝对是科尔斯的作品.这是失败的考验.所以我猜测试是因为我不知道的原因没有看到它.
目前我正在尝试为我正在工作的学校项目设置Spring MVC Controller测试.通常我在像Laravel这样的php和框架中编程,所以这对我来说很新.问题是我无法弄清楚如何解决在加载ApplicationContext时不断弹出的问题.任何帮助表示赞赏.
更新:
我现在被告知,测试用例不会在我的应用服务器中使用jndi ref.所以这个引用在测试用例上会失败,它在启动应用程序时运行良好.现在我创建了第二个文件servlet-test.xml (listed below),它在端口3306上使用对数据库的引用.我只在测试时使用此文件而不是在启动应用程序时.但是当我使用这种方法时,我得到了 Following error: Error creating bean with name 'productController': Injection of autowired dependencies failed.欢迎任何帮助,因为我正在努力为我的学校项目设置MVC控制器测试.我一直在和我一起工作的其他学生也遇到了同样的问题,所以我也可以帮助他们.
我怀疑问题如下,但我不知道如何解决这个问题.
Error creating bean with name 'myDataSource' defined in URL
[file:web/WEB-INF/servlet.xml]: Invocation of init method failed;
nested exception is javax.naming.NamingException: Lookup failed for
'java:app/fotoproducent' ...
Run Code Online (Sandbox Code Playgroud)
错误堆栈跟踪
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in URL [file:web/WEB-INF/servlet.xml]: Cannot resolve reference to bean 'myDataSource' while setting bean property 'dataSource'; nested …Run Code Online (Sandbox Code Playgroud) 由于我从 1.x 迁移到 Spring Boot 2.0.5,无意禁用安全性,我无法让测试角色在模拟 MVC 测试中工作:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ApplicationsControllerShould {
...
@Autowired
private MockMvc mockMvc;
private ObjectMapper mapper = new ObjectMapper();
@Test
@WithMockUser(roles = "ADMIN")
public void handle_CRUD_for_applications() throws Exception {
Application app = Application.builder()
.code(APP_CODE).name(APP_NAME)
.build();
mockMvc.perform(post("/applications")
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(mapper.writeValueAsString(app)))
.andExpect(authenticated())
.andExpect(status().isOk()); // failure 403!
...
Run Code Online (Sandbox Code Playgroud)
我的控制器端点甚至没有受到保护!
@RestController
@RequestMapping("/applications")
public class ApplicationsController {
...
@PostMapping
public Application addApplication(@RequestBody Application application) {
Assert.isTrue(!applicationsDao.existsById(application.getCode()), "Application code already exists: " + application.getCode());
return applicationsDao.save(application);
}
}
Run Code Online (Sandbox Code Playgroud)
所以我在测试中有一个会话(当@WithMockUser …
spring spring-mvc spring-security spring-mvc-test spring-boot
有什么方法forward:/可以在JUnit测试中测试从Spring MVC控制器返回的视图的功能?
我使用的MockMvc是Spring 3.2中的功能,在某些情况下,我的控制器会转发到另一个(通过返回的视图名称forward:/pathHandledByController)。
能够断言,在进行此转发时,将@ModelAttribute很好地应用了第二个控制器中的所有s,并且所有过程均正常进行。不幸的是MockMvc,我只能断言返回的视图名称以开头forward:/。
有什么方法可以测试而不必像Jetty那样分解整个Web应用程序吗?我已经将许多服务纳入了MVC应用程序,我将如何创建一个使用单独的Spring配置(来自src/test/resources)并模拟这些服务的Web应用程序?
我需要在具有以下gradle依赖的项目中使用Cassandra:
compile "org.springframework.boot:spring-boot-starter-data-cassandra"
Run Code Online (Sandbox Code Playgroud)
问题是,尽管将Cassandra AutoConfiguration类标记为从单元测试中排除,但spring仍会以某种方式尝试实例化与此依赖性相关的类。
这是我的单元测试:
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
@RunWith( SpringRunner.class )
@SpringBootTest
@AutoConfigureMockMvc
@EnableAutoConfiguration( exclude = {
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration.class,
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration.class
} )
public class HealthTest {
@Autowired
private MockMvc mockMvc;
@Test
public void contextLoads() {
Assert.assertNotNull( mockMvc );
}
@Test
public void healthControllerIsUp() throws Exception {
mockMvc.perform( MockMvcRequestBuilders.get( "/health" ) )
.andExpect( MockMvcResultMatchers.status().isOk() );
}
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误,显然是因为Spring无法实例化群集对象。
java.lang.IllegalStateException: Failed …Run Code Online (Sandbox Code Playgroud) cassandra spring-mvc-test spring-boot spring-data-cassandra spring-boot-starter
spring-mvc-test ×10
spring-mvc ×7
spring ×5
spring-boot ×5
java ×2
cassandra ×1
cors ×1
hibernate ×1
jetty ×1
junit ×1
junit5 ×1
spock ×1
spring-junit ×1
spring-test ×1
xml ×1