功能语言中的单元测试如何工作



我想知道如何用功能语言编写良好的单元测试。测试非常基本的功能并不难,但我不明白我应该如何测试使用其他功能的功能。

例如:
在面向对象的世界中,我自己测试了非常基本的功能,然后在测试更复杂的功能

时模拟它
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.addMultiplier.multiply,我可以通过模拟这些测试来测试Example.execute并期望adder被称为n<mmultiplier,否则会被调用。

但是我该如何用功能性语言进行操作?我可以易于测试addmultiply功能,并从中撰写我的execute

execute : Int -> Int -> Int
execute = 
    if n < m then add n m
    else multiply n m

现在要测试execute,我不能简单地期望addmultiply被调用,因为我无法模拟它们。实际上,我必须已经为add编写的所有测试,如果n<m执行它们,并对multiply进行所有测试,否则。这意味着我两次测试了这两个功能。

那么,测试较小函数的正确功能方式是什么,对于较大的功能假设它们有效,只需检查是否满足正确的条件?

您的execute功能具有输入值和预期输出 - 您不应该关心其实现方式。
您将编写涵盖所有execute功能的测试。
如果要实施,您决定重复使用addmultiply方法以及execute功能通行证的所有测试 - 好工作 - 您已经创建了可重复使用的功能。

想象以后您将决定更改add方法的行为 - 您将更改add功能的测试以满足新要求 - 当您在更改后运行所有测试时 - 所有测试通过,execute功能的测试也将通过,因为您模拟了它,但实际上execute功能已断开...

将"单位"视为行为单位。摘要仅使测试缓慢或使用全局应用状态的组件。

函数multiplyadd是实现详细信息,将通过"高阶"功能进行测试。

最新更新