2

这个答案让我很生气,因为我从来没有理解过如何处理动态语言中的参数类型与来自 Java 的静态语言(我的观点被告知或变形 - 如你所愿)。

给定一个采用动态语言参数 bar 的方法 foo,在编译时不强制执行 bar 的类型。上面链接的答案(以及我通常看到的答案)是您需要使用动态语言正确进行单元测试。

但在某些时候,单元外的某些东西会调用该方法。假设这是一个重量级的对象,将在任何使用它的类的单元测试中被模拟。现在你有很多类调用这个方法,你需要改变类型。为简单起见,它曾经接受一个数字,但现在需要一个字母数字,并且您需要使用专门用于字符串而不是具有新要求的数字对象的方法。

您如何更改它并知道调用代码将被修复?当然,如果您只是更改它,您的单元测试将失败,但由于您需要故意更改它,因此您表面上会修复您的单元测试。你怎么知道修复调用代码?我的意思不仅仅是概念上你知道多少,我的意思是你怎么知道你已经找到了所有的调用者并且真的可以说它已经改变了。

似乎只有非常全面的集成测试才能为您提供保证。我错过了什么吗?

4

6 回答 6

2

我需要 15 个字符才能发布,但答案是 4 个字符长:grep。

于 2009-09-25T02:29:44.763 回答
2

我认为你已经给出了一个很好的具体例子来说明静态类型的优点之一。动态类型需要您自己找到所有这些呼叫位置。不过,这实际上并不是很困难——它只是代码中的文本搜索。这就是权衡:编译器可以交叉引用您的代码并确保一切匹配,而不是在整个代码中没有分散注意力的类型标签,这让您感到很舒服。

于 2009-09-25T02:31:36.493 回答
2
  1. 防守代码。使更改在新方法中向后兼容。派发参数的类型;CLOS让这一切变得简单。

  2. 使用编辑器或 IDE 的“谁来电”功能。

于 2009-09-25T02:32:57.083 回答
1

这似乎更像是一个重构问题而不是单元测试问题。

通过确保特定函数中所需的所有属性和方法都存在并返回预期结果,可以对参数进行有效的单元测试。接口与类型无关。

于 2009-09-25T02:30:38.457 回答
1

简短的回答就是“一直进行更多的单元测试”。

唯一重要的是新类型还具有所需的方法。所以如果ClassA有 Method1() ,它接受一个参数并obj调用- 对 obj 的唯一约束是它响应这些消息。如果您更改实现以调用以前不存在的方法,则执行 A 类的测试会失败。obj#M1()obj#M2()Foo()

接下来,如果ClassB调用A#Method1()作为其功能的一部分,如果 Class B 正在传递一个 obj,它的测试将失败,该 obj 确实具有所需的方法。如果没有达到 B 的要求行为,它的测试应该失败,这应该指向 B 中所需的更改。

于 2009-09-25T02:30:43.263 回答
1

动态语言开发人员需要复制静态类型的优势,即通过让工具自动发现这些错误。在大多数情况下,这涉及类型推断工具。推理本身非常困难(我正在为 PHP 写我的博士学位),但使用这些工具并不是非常困难。

有以下错误查找工具:

对于 PHP,phc只需很少的工作量就可以做到这一点。

总的来说,当你没有静态类型时,你需要一个工具来获得好处。

于 2009-09-30T11:34:59.357 回答