1

我正在用 EUnit 编写测试,一些被测单元需要通过file:consult/1读取数据文件。我的测试对/priv中可用的数据进行了假设,但生产中的数据会有所不同。实现这一目标的最佳方法是什么?

我是 Erlang 的新手,我想到了一些让我觉得有点难看的解决方案。例如,

  • 将这两个文件放在/priv中并使用宏(例如,“-ifdef(EUNIT)”)来确定将哪个文件传递给file:consult/1。这对我来说似乎太脆弱/容易出错。
  • 让 Rebar 将正确的文件复制到/priv

如果我试图做一些根本错误的事情,请随时指出。情况可能就是这样。

有一个更好的方法吗?

4

1 回答 1

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  ...  ] 

它将允许您在生产中使用较短的版本,而更长的版本仅用于您的测试。

于 2014-11-23T16:51:53.870 回答