This answer与我一起对我从未理解过如何处理动态语言中的参数类型而不是静态语言(我的观点被告知或变形 - 如您所愿)来自Java。{{3}}。 p>
给定一个方法foo,它采用动态语言中的参数栏,在编译时没有强制执行bar类型。上面链接的答案(以及我通常看到的答案)是你需要用动态语言正确地进行单元测试。
但是在某些时候,单位之外的东西会称之为该方法。假设这是一个重量级的对象,将在使用它的类的任何单元测试中进行模拟。现在您有许多调用此方法的类,您需要更改类型。为了简单起见,它过去需要一个数字,但现在需要一个字母数字,你需要使用一个特定于字符串的方法,而不是一个具有新要求的数字对象。
如何更改它并知道调用代码将被修复?当然,如果你只是改变它,你的单元测试将失败,但由于你需要故意改变它,你表面上会修复你的单元测试。你怎么知道修复调用代码?我不仅仅意味着你在概念上如何知道,我的意思是你怎么知道你找到了所有的来电者并且真的可以说它已经改变了。
似乎只有非常全面的集成测试才能为您提供保证。我错过了什么吗?
答案 0 :(得分:2)
我需要发布15个字符,但答案是四个字符:grep。
答案 1 :(得分:2)
我认为你给出了静态类型的一个优点的一个很好的具体例子。动态类型要求您自己查找所有这些呼叫位置。这实际上并不是很困难 - 它只是代码中的文本搜索。这是一个权衡:编译器可以交叉引用您的代码并确保所有内容匹配的舒适性,而不是在整个代码中没有令人分心的类型标记。
答案 2 :(得分:2)
防守代码。在新方法中使更改向后兼容。派遣论证的类型; CLOS让这很容易。
使用编辑器或IDE的“who calls”功能。
答案 3 :(得分:1)
这似乎更像是一个重构问题,而不是单元测试问题。
通过确保特定函数中所需的所有属性和方法都存在并返回预期结果,可以对参数进行有效的单元测试。重要的是接口不是类型。
答案 4 :(得分:1)
简短的回答是“更多的单元测试”。
唯一重要的是新类型还有所需的方法。因此,如果ClassA
具有Method1(),它接受参数obj
并调用obj#M1()
和obj#M2()
- 对obj的唯一约束是它响应这些消息。如果您更改实现以调用先前不存在的方法Foo()
,则执行A类的测试将失败。
接下来如果ClassB
调用A#Method1()
作为其功能的一部分,如果B类传递一个具有所需方法的obj,则其测试将失败。如果未达到B的所需行为,则其测试应该失败,并且应该指向B中所需的更改。
答案 5 :(得分:1)
动态语言开发人员需要复制静态类型的优势,即通过让工具自动找到这些错误。在大多数情况下,这涉及类型推理工具。推理本身非常困难(我正在为PHP编写我的博士学位),但使用这些工具并不是非常困难。
有以下错误查找工具:
对于PHP,phc只需很少的工作即可完成此任务。
总的来说,当你没有静态类型时,你需要一个工具来获得好处。