springboot 测试增加模拟安全处理
根据springboot1.4提供的测试方式,给测试类增加注解可以直接对RestController类进行测试非常方便。
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class DeptControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testGet() {
Dept data = this.restTemplate.getForObject("/dept/1", Dept.class);
assertThat(data.getId()).isEqualTo(1);
}
}
但实际Rest接口通常都有安全,想模拟header安全需要将header信息注入,查完试了几种方式,做下备忘。
首选先弄一个处理header安全信息的类
import java.io.IOException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
public class UserAgentInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
HttpHeaders headers = request.getHeaders();
//todo 模拟安全信息并注入header中
headers.add("xxx", xxx);
return execution.execute(request, body);
}
}
下面就是如何把这个类注入到测试中
方案1
通过在测试类中直接增加TestConfiguration 来进行额外Bean 注入实现
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class DeptControllerTest {
....
@TestConfiguration
static class Config {
@Bean
public RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder().additionalInterceptors(new UserAgentInterceptor());
}
}
}
第一次用的这种方式,可行,但需要在每个测试类里都写不太爽。
方案2
尝试把@TestConfiguration弄到一个基类或者顶级类里去,直接实现一个配置类
@TestConfiguration
public class MyTestConfig {
@Bean
public RestTemplateBuilder restTemplate() {
return new RestTemplateBuilder().additionalInterceptors(new UserAgentInterceptor());
}
}
有了这个类后在@SpringBootTest注解中进行声明
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT, classes=MyTestConfig.class)
public class DeptControllerTest {
...
}
可行,比之前少加一些代码,还是需要每个测试类增加声明,不过其实也可以了。
方案3
在主入口增加TestConfiguration 类的包扫描,放到扫描到的组件包中
@SpringBootApplication
@ComponentScan(basePackages = {"com.lee.springboot"})
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
其实MyTestConfig本来就在com.lee.springboot包下,但classpath在test中,如果不增加@ComponentScan(basePackages = {“com.lee.springboot”})就不扫描,增加了就扫描了,这原因还没研究。