Spring Boot Test MalformedURLException:未知协议:类路径

Posted

技术标签:

【中文标题】Spring Boot Test MalformedURLException:未知协议:类路径【英文标题】:Spring Boot Test MalformedURLException: unknown protocol: classpath 【发布时间】:2019-03-26 22:11:23 【问题描述】:

如果在 Spring Boot 应用程序中使用 java.net.URL,使用 classpath 协议,它会按预期工作,因为 Spring Boot 注册了 URLStreamHandlerFactory。例如new URL("classpath: someFile.whatever").

但是当这个代码作为 JUnit 测试执行时,java.net.MalformedURLException: unknown protocol: classpathexception 被抛出。

在为 JUnit 测试初始化​​ Spring 上下文时,似乎没有注册适当的 URLStreamHandlerFactory

重现步骤:

1) 创建 Spring Boot Starter 项目(例如,仅使用 starter Web)。

2) 在src/main/resources 中添加test.json 文件

3) 添加以下 bean:

@Component
public class MyComponent 
    public MyComponent() throws MalformedURLException 
        URL testJson = new URL("classpath: test.json");
        System.out.println(testJson);
    

4) 以 java 应用程序启动应用程序可以正常工作

5) 运行默认的“contextLoads”测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringUrlTestApplicationTests 

    @Test
    public void contextLoads() 
    


java.net.MalformedURLException: unknown protocol: classpath异常被抛出。

在 JUnit 测试中使用带有类路径资源的 URL 的适当方法是什么?

在实际用例中,我无法更改 new URL("classpath: test.json"),因为它来自第 3 方库。

尝试将test.json 复制到src/test/resources 中,以测试错误是否可能是由于缺少资源导致的 - 没有成功。

【问题讨论】:

如果不能更改第三方库define the URLhandler,否则容易使用@Resource - examples 【参考方案1】:

最短和最简单的方法是在测试执行之前创建简单的方法,即为“类路径”协议创建和注册处理程序。

    @BeforeClass
    public static void init() 
        org.apache.catalina.webresources.TomcatURLStreamHandlerFactory.getInstance();
    

我刚刚检查过,它工作正常。这种方法也在 spring-boot 应用程序内部使用

【讨论】:

非常感谢,博里诺!【参考方案2】:

问题是处理协议的类是org.apache.catalina.webresources.TomcatURLStreamHandlerFactory。你可以用这个来修复你的测试:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MalformedUrlApplicationTests 

    @Test
    public void contextLoads() 
    


但我认为@borino 的回答更好。

【讨论】:

非常感谢,阿瓦加斯!【参考方案3】:

我认为你可以尝试 Autowire ResourceLoader,并使用 resourceLoader.getResource("classpath:/test.json") 加载文件,它会从资源文件夹加载文件。

【讨论】:

我应该在哪里做呢?在测试班?正如我所说,我想避免使用 java.net.URL 更改包含代码的库。 这里有很多选项,在被测资源文件夹中使用静态文件,或者将 JSON 模拟为字符串 另一种解决方案,如果您需要调用实际 URL 的集成测试,只需调用内部将调用实际 URL 的实现方法(只要您使用 @SpringBootTest),所有内容都将被加载并调用 URL,然后您可以进行任何测试或模拟。 petrikainulainen.net/programming/spring-framework/…【参考方案4】:

我更喜欢使用 apache commons 的以下方式:

String url = IOUtils.toString(
    this.getClass().getResourceAsStream("test.json"),"UTF-8"
);
URL testJson = new URL(url);

文件 test.json => 你可以保存在 src/test/resources 文件夹中 -> 它将从这里加载,使用 maven 它适用于我

更多类似的方法在这里可用 How to read a text-file resource into Java unit test?

【讨论】:

【参考方案5】:

Spring 没有可以处理 "classpath:" 协议的 URL 的 URLStreamHandler。 Spring 使用ResourceLoader API 处理此协议。加载资源后,您可以获得它的 URL。

不过,Java 提供了一种支持非标准协议的机制。我找到了一个 *** 条目,应该可以回答您的问题。

Supporting Classpath URLs

【讨论】:

以上是关于Spring Boot Test MalformedURLException:未知协议:类路径的主要内容,如果未能解决你的问题,请参考以下文章

SPRING BOOT 15.1 TEST

Spring boot test

Spring boot test

Spring boot test

spring boot进行Test测试

找不到 SpringApplicationConfiguration:错误的 spring-boot-starter-test 内容?