我正在寻找有关如何编写Main模块中定义的Haskell代码的测试的帮助.
我想测试的项目是一个cabal包,我在其中定义了多个可执行文件.每个可执行代码只声明一个文件(每个项目euler问题一个),我通常使用该cabal run命令单独运行它们.
我曾尝试在Main模块中编写测试,但在编译时,找不到我要测试的函数("不在范围内"错误).
在这种情况下编写测试的正确方法是什么?
有关信息,以下是我的项目的目录布局:
pe/ # root
pe.cabal
src/
Util.hs
Problem001.hs # "module Main where" and declares a main function
Problem002.hs # "module Main where" and declares a main function
(...)
test/
TestProblem001.hs # "module Main where" and declares a main function
Run Code Online (Sandbox Code Playgroud)
以下是pe.cabal的摘录:
test-suite test-all
hs-source-dirs: test
type: exitcode-stdio-1.0
main-is: TestProblem001.hs
build-depends: base, HUnit, Cabal >= 1.9.2
executable problem-001
hs-source-dirs: src
main-is: Problem001.hs
build-depends: base
ghc-options: -Wall -Werror -O2
Run Code Online (Sandbox Code Playgroud)
[编辑]
由于我找不到任何资源来满足这个要求,我选择了一个更容易测试的项目架构:问题被定义为库而不是单个可执行文件.
我正在研究的项目由多个模块组成,使用maven构建.某些模块中的测试代码依赖于来自其他模块的测试代码.这些依赖关系声明如下.
在依赖模块中:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
在依赖于前一个模块的模块中:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>themodulename</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
使用此配置,可以成功执行maven 安装阶段.但是尝试运行编译或测试阶段失败,因为无法解析测试jar文件依赖性.
看一下测试jar目标,它似乎被配置为在包阶段默认运行,我认为这是导致问题的原因.
然后,我尝试在编译阶段强制执行此目标,方法是将第一个配置修改为:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
查看调试日志,我可以看到目标现在在编译阶段执行,但是:
[WARNING] JAR will be empty - no content was marked for inclusion!
Run Code Online (Sandbox Code Playgroud)
我尝试将包含配置为**/*并确认默认的testClassesDirectory设置为正确的,但我仍然得到相同的警告.
我可以看到运行编译阶段后test-classes文件夹不存在,这看起来很正常,但即使它在运行测试阶段后存在,并且它包含文件,我仍然会得到"JAR将为空"警告.
有没有人知道修复这个配置,以便我可以成功运行编译或测试阶段?
使用Jackson json库,可以通过使用来反序列化对象@JsonCreator,并给出表示输入json的"顶级"映射,如下所示:
class MyClass {
final int field;
@JsonCreator
public MyClass(Map<String, Object> map) {
this.field = (int) map.get("theInt");
}
}
Run Code Online (Sandbox Code Playgroud)
甚至是静态工厂方法:
class MyClass {
final int field;
public MyClass(int theInt) {
this.field = theInt;
}
@JsonCreator
static MyClass create(Map<String, Object> map) {
return new MyClass((int) map.get("theInt"));
}
}
Run Code Online (Sandbox Code Playgroud)
前面的示例可以处理以下类型的json输入:
{
"key1":"value1",
"key2":"value2",
"key3":"value3"
}
Run Code Online (Sandbox Code Playgroud)
这在我的情况下特别有用,因为我想反序列化一个我不知道的json结构.通过访问我称之为"顶级地图"的内容,可以简化操作.
我想以这种方式反序列化我的对象,因为它也允许创建不可变对象,而不是使用@JsonAnySetter不允许这样的对象,@JsonProperty我不能使用它,因为我不提前知道属性名称,如前所述.
然后再往前走,我想在我的工厂方法中注入一些配置,而杰克逊允许通过使用@JacksonInject和调用来withInjectableValues(InjectableValues)实现ObjectMapper.
这最终是我想要使用的代码类型:
class MyClass {
final MyField[] myFields;
public MyClass(MyField... myFields) { …Run Code Online (Sandbox Code Playgroud) java ×2
testing ×2
cabal ×1
dependencies ×1
haskell ×1
jackson ×1
json ×1
map ×1
maven ×1
maven-plugin ×1