我正在用EUnit编写测试,一些被测单元需要通过文件读取数据文件:consult / 1 。我的测试假设了 / priv 中可用的数据,但生产中的数据会有所不同。实现这一目标的最佳方法是什么?
我是Erlang的新手,我想到了一些对我来说有点难看的解决方案。例如,
另外,请随意指出我是否正在尝试做一些根本错误的事情。情况可能就是这样。
有更好的方法吗?
答案 0 :(得分:1)
我认为你的两个解决方案都能奏效。这是维护此类测试的问题,而且这两个测试都依赖于一些外部设置(文件存在,并且具有正确的数据)。
对我来说,最简单的方法是将此类文件的内容保存在给定测试的本地,这样就可以模拟,并使file:consult/1
返回您想要的值。
7> meck:new(file, [unstick, passthrough]).
ok
8> meck:expect(file, consult, fun( _File ) -> {some, data} end).
ok
9> file:consult(any_file_at_all).
{some,data}
它会起作用,但还有两件事你可以做。
首先,您根本不应该测试file:consult/1
。它是标准库的一部分,并且可以假设它可以全部工作。您应该测试使用从此文件中读取的数据的函数,而不是这样做;当然还会向他们传递一些“测试中创建的”数据。它将为您提供数据源之间的良好分离,以及解析(处理)它。以后,通过调用外部服务或类似的东西来替换file:consult
可能更简单。
其他问题是测试某些东西的问题应该是你的难闻气味的迹象。您可能会考虑重新设计系统。我不是说你必须这样做,但这些问题是很好的指标。如果您测试某些功能x,并且您希望它在生产和其他测试中表现一种方式(读取一个文件或另一个文件),那么应该将这种行为注入其中。或者换句话说,也许你应该读取的函数应该是这个函数中的参数。如果您希望在生产代码中仍然有一些“默认文件读取”功能,您可以使用类似的东西
function_with_file_consult(A, B, C) ->
function_with_file_consult(A, B, C, "default_file.dat").
function_with_file_consult(A, B, C, File) ->
[ ... actual function logic ... ]
它允许您在生产中使用更短的版本,并且仅在您的测试中使用更长的版本。