我有一个Web应用程序项目,我正在尝试使用FreeMarker模板对使用FreeMarker模板创建文件的方法进行单元测试。我的方法createFile()应该采用MyFile类型 - 包含要创建的文件名和rootMap FreeMarker需要的模板名称 - 并使用我提供的模板创建文件。
我正在关注Freemarker manual以设置模板加载器。问题是,我正在使用TemplateLoader setClassForTemplateLoading(Class,String)方法来查找模板路径。此模板加载器使用Class.getResource()来获取类路径。
但是,因为我正在使用Maven,我的/ src / main / java中的java代码,/ src / main / webapp / templates /中的模板以及/ src / test / java中的测试代码。因此,我的Class.getResource(“/”)(根类路径)始终返回<PATH_TO_PROJECT>/target/test-classes/
。
由于我将部署战争,我不能使用setDirectoryForTemplateLoading(File)。此外,由于我正在测试我的应用程序,因此我没有与setServletContextForTemplateLoading(Object,String)一起使用的ServletContext。
如何从测试用例中访问我的模板文件夹?
这是我的测试代码的简化示例(我使用mockito来模拟MyFile类的行为):
private MyFile myFile;
private FileGenerator fileGenerator;
@Before
public void setUp() {
myFile = new MyFile(...);
fileGenerator = new FileGenerator(myFile, ...);
}
@Test
public void shouldCreateFile() {
final MyFile mockedMyFile = spy(file);
final Map<String, Object> rootMap = new HashMap<String, Object>();
// populates rootMap with stuff needed for the Template
// mocking method return
when(mockedMyFile.getRootMap()).thenReturn(rootMap);
// replacing the MyFile implementation with my Mock
fileGenerator.setMyFile(mockedMyFile);
// calling the method I want to test
fileGenerator.createFile();
assertTrue(MyFile.getFile().exists());
}
这是我正在测试的代码的简化:
public void createFile() {
final Configuration cfg = new Configuration();
cfg.setClassForTemplateLoading(getClass(), "templates/");
try {
myFile.getFile().createNewFile();
final Template template = cfg.getTemplate("template.ftl");
final Writer writer = new FileWriter(myFile.getFile());
template.process(myFile.getRootMap(), writer);
writer.flush();
writer.close();
}
// exception handling
}
答案 0 :(得分:0)
我应用了Charles Forsythe的建议,结果很好。
我刚刚将一个templateLoader成员添加到FileGenerator类中,并使用自己的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
}
问题解决了。在我的生产代码中,我使用ClassTemplateLoader而不是FileTemplateLoader。