我想知道如何用函数式语言编写好的单元测试。测试非常基本的功能并不难,但我不明白我应该如何测试使用其他功能的功能。
例如:
在面向对象的世界中,我自己测试非常基本的功能,并在测试更复杂的函数时模拟它
class Example {
internal var adder: Adder = AdderImpl()
internal var multiplier: Multiplier = MultiplierImpl()
fun execute(n: Int, m: Int): Int =
if (n < m) adder.add(n, m)
else multiplier.multiply(n, m)
}
如果对Adder.add
和Multiplier.multiply
进行了测试,我可以通过模拟这些来测试Example.execute
,并期望为adder
和{{1}调用n<m
否则被称为。
但是我怎么用功能语言呢?我可以轻松测试multiplier
和add
函数,并从中构建multiply
execute
现在要测试execute : Int -> Int -> Int
execute =
if n < m then add n m
else multiply n m
我不能简单地期望调用execute
或add
,因为我无法模仿它们。我实际上必须完成我为multiply
编写的所有测试,并在add
执行它们,否则执行n<m
的所有测试。这意味着我测试了这两个函数两次。
那么测试较小函数和更大函数的正确函数方法是什么假设它们有效并且只检查它们是否在满足正确条件时被调用?
答案 0 :(得分:4)
您的execute
功能具有输入值和预期输出 - 您不应该关心它的实现方式。
您将编写涵盖execute
函数的所有案例的测试
如果要实现,您决定重用add
和multiply
方法以及execute
函数传递的所有测试 - 好工作 - 您已经创建了可重用的函数。
想象一下,您将决定更改add
方法的行为 - 您将更改add
函数的测试以满足新要求 - 当您在更改后运行所有测试时 - 所有测试都通过,测试{ {1}}函数也会传递,因为你嘲笑它,但实际上现在execute
函数被破坏了......
考虑&#34;单位&#34;作为行为单位。摘要只有使测试变慢的组件或使用全局应用程序的组件。
execute
add
这样的函数是实现细节,将通过&#34;更高阶&#34;功能