我正在为我的应用程序的REST API使用TestNG编写自动化测试。该应用程序具有一个RestController,其中包含一个@Autowired服务类。当使用HTTP GET请求调用REST端点时,该服务将查找XML文件的存储目录,将其内容转换为对象并将其存储在数据库中。对于我的问题,重要的是,存储目录的路径存储在/src/main/resources/application.yml(source.storage)中,并通过@Value批注导入。
现在,我在src / test / resources / application.yml中也具有source.storage属性,它指向src / test中的另一个目录,我在其中存储测试XML文件,并使用再次@Value注释。我的测试使用HTTP GET调用REST端点。但是,该服务似乎仍在主application.yml中绘制source.storage属性,而我希望该值被测试application.yml文件中的值覆盖。换句话说,该服务尝试从应用程序存储目录而不是从我的测试存储导入XML文件。
@ActiveProfiles和@TestPropertySource对我似乎不起作用。扫描主应用程序.yml的存储属性是不可行的,因为最后,该application.yml是从Spring Cloud Config中提取的,我不知道主应用程序.yml的位置。
有没有一种方法可以使@Autowired服务从测试application.yml中而不是从主要应用程序中提取source.storage属性?
任何建议将不胜感激。
谢谢,彼得
答案 0 :(得分:1)
好吧,这实际上取决于您要构建的内容,如果它是控制器的某种单元测试或更可能是集成测试。 tutorial对此方法进行了解释。
如果您尝试编写集成测试,这似乎更适合您的问题,那么@ActiveProfiles
或@TestPropertySource
应该适合您。我建议使用配置文件,在具有许多属性的不断增长的应用程序中,只需替换一些用于测试的属性会更加方便。以下是为控制器端点编写集成测试时为我工作的设置:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class AreaControllerTest {
@Autowired
TestRestTemplate rest;
@MockBean
private JobExecutor jobExecutor;
@Test
public void test01_List() {
//
}
@Test
public void test02_Get() {
//
}
// ...
}
有几件重要的事情。
src/test/resources/application-test.properties
中,并按照application.properties
注释的建议覆盖标准@ActiveProfiles("test")
中的属性。@RunWith(SpringRunner.class)
,有关TestNG的替代方法,请参考this SO question。@SpringBootTest
批注将启动整个应用程序上下文。@FixMethodOrder
和@DirtiesContext
是测试用例的进一步设置,并非必需。@MockBean
注释,在这种情况下,我们不想使用JobExecutor
的实际实现,因此我们将其替换为模拟。如果要编写单元测试,而只想单独检查控制器和服务的逻辑,则必须有两个测试类,每个测试类都测试各自的类。测试服务应该是标准的单元测试,测试控制器比较棘手,可能更倾向于部分集成测试。如果您是这种情况,我建议您使用上述教程中介绍的MockMvc
方法。那里的小片段:
@RunWith(SpringRunner.class)
@WebMvcTest(GreetingController.class)
public class WebMockTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private GreetingService service;
@Test
public void greetingShouldReturnMessageFromService() throws Exception {
when(service.greet()).thenReturn("Hello Mock");
this.mockMvc.perform(get("/greeting")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello Mock")));
}
}
请注意@MockBean
注释,该注释模拟服务,您可以在其中指定自己的模拟行为。这一点很关键,因为这种测试不会加载整个应用程序上下文,而只会加载MVC上下文,因此服务不可用。同样,在集成测试中,@RunWith(SpringRunner.class)
注释是必不可少的。最后,@WebMvcTest(GreetingController.class)
仅启动GreetingController
类的MVC上下文,而不是整个应用程序。
答案 1 :(得分:0)
您可以尝试将属性直接提供给Spring Boot测试。
UITextView
关于应用程序选择了错误的属性源,您还应该检查应用程序是否正确构建。