使用SpringBoot集成Jersey做单元测试时遇到了application.xml找不到的提示。详情如下:
Caused by: java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330) ... 61 more
测试使用的代码大致如下:
import com.zhyea.jspy.QueryServiceApplication; import com.zhyea.jspy.bean.Probe; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.ws.rs.core.Application; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = MySpringApplication.class) public class MyResourceTest extends JerseyTest { @Override protected Application configure() { return new ResourceConfig(MyResource.class); } @Test public void testGet() { final Probe p = target("/api/probe/get/106").request().get(Probe.class); System.out.println(p); } }
原因是SpringBoot的Context和Jersey的Context是不同的。要修复这个问题可以基于SpringBoot的Context来构建测试时Jersey的Context,但是这样做也会遇到一些问题。具体什么问题懒得说了。直接说解决方案:跳过Jersey的Context,不使用JerseyTest抽象类,直接自行创建WebTarget实例。
看一个测试超类代码示例好了:
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = MyApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class JerseyTestBase { private static Logger logger = LoggerFactory.getLogger(JerseyTestBase.class); @Value("${local.server.port}") private int port; public Response get(String path) { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:" + port + "/api" + path); return target.request(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).get(); } }
就这样。
#############