Java 如何在单元测试期间访问.war类路径中的文件?

Java 如何在单元测试期间访问.war类路径中的文件?,java,unit-testing,maven,web-applications,freemarker,Java,Unit Testing,Maven,Web Applications,Freemarker,我有一个web应用程序项目,我正在尝试对一个使用FreeMarker模板创建文件的方法进行单元测试。我的方法createFile()应该采用MyFile类型(包含要创建的文件名、rootMap FreeMarker需要的文件名和模板名),并使用我提供的模板创建一个文件 我将按照以下步骤设置模板加载器。问题是,我正在使用TemplateLoader setClassForTemplateLoading(类,字符串)方法来查找模板路径。此模板加载器使用Class.getResource()获取类路径

我有一个web应用程序项目,我正在尝试对一个使用FreeMarker模板创建文件的方法进行单元测试。我的方法createFile()应该采用MyFile类型(包含要创建的文件名、rootMap FreeMarker需要的文件名和模板名),并使用我提供的模板创建一个文件

我将按照以下步骤设置模板加载器。问题是,我正在使用TemplateLoader setClassForTemplateLoading(类,字符串)方法来查找模板路径。此模板加载器使用Class.getResource()获取类路径

但是,由于我使用的是Maven,我的java代码在/src/main/java中,模板在/src/main/webapp/templates/中,测试代码在/src/test/java中。因此,my Class.getResource(“/”)(根类路径)总是返回
/target/test classes/

由于我将部署war,因此无法使用setDirectoryForTemplateLoading(文件)。另外,因为我正在测试我的应用程序,所以我没有ServletContext用于setServletContextForTemplateLoading(对象,字符串)

如何从测试用例访问模板文件夹

下面是我的测试代码的一个简化示例(我使用mockito模拟MyFile类的行为):


我采纳了查尔斯·福赛斯的建议,结果很好

我刚刚向FileGenerator类添加了一个templateLoader成员,它有自己的getter和setter

接下来,在我的createFile方法中,我使用Configuration类中的方法setTemplateLoader(TemplateLoader),如下所示:

public void createFile() {
    final Configuration cfg = new Configuration();
    // Changed
    cfg.setTemplateLoader(templateLoader);
    // the rest
}
最后,我只是为我的测试创建了一个模板加载器:

@Test
public void shouldCreateFile() {
    final MyFile mockedMyFile = spy(file);
    final Map<String, Object> rootMap = new HashMap<String, Object>();
    TemplateLoader templateLoader = null;

    try {
        templateLoader = new FileTemplateLoader(new File("<PATH TO TEMPLATE FOLDER>"));
    } catch (final IOException e) {
        e.printStackTrace();
    }

    gerador.setTemplateLoader(templateLoader);
    // the rest
}
@测试
public void shouldCreateFile(){
最终MyFile mockedMyFile=spy(文件);
final-Map-rootMap=new-HashMap();
TemplateLoader TemplateLoader=null;
试一试{
templateLoader=新文件templateLoader(新文件(“”);
}捕获(最终IOE例外){
e、 printStackTrace();
}
gerador.setTemplateLoader(模板装载机);
//其余的
}

问题解决了。在我的产品代码中,我使用ClassTemplateLoader而不是FileTemplateLoader。

既然您已经在使用mockito,那么您可以尝试powermock来模拟静态/最终/私有方法,例如Class.getResource(),真的在测试代码中使用/src/main/test,而不是src/test/java吗?@Grove我会试试看!Thanks@khmarbaise哦,你是对的,修正了我的问题,你可以修改你的类以便于测试。Freemarker
Configuration
对象通常作为单例使用——不是为每次调用构建的。如果
配置
被注入到类中,那么您可以模拟它,或者在测试中使用备用模板加载程序。
public void createFile() {
    final Configuration cfg = new Configuration();
    // Changed
    cfg.setTemplateLoader(templateLoader);
    // the rest
}
@Test
public void shouldCreateFile() {
    final MyFile mockedMyFile = spy(file);
    final Map<String, Object> rootMap = new HashMap<String, Object>();
    TemplateLoader templateLoader = null;

    try {
        templateLoader = new FileTemplateLoader(new File("<PATH TO TEMPLATE FOLDER>"));
    } catch (final IOException e) {
        e.printStackTrace();
    }

    gerador.setTemplateLoader(templateLoader);
    // the rest
}