2016-12-23 30 views
1

我一直在努力理解由jmockit Mocking API支持的类雷区。我发现我认为是File的一个bug,但是这个问题只是简单的说了“不要模拟文件或路径”,这是没有任何解释的。有人能在这里帮助我理解为什么某些类不应该被嘲笑,以及我应该如何解决这个问题。我正在尝试通过bug报告向图书馆作出贡献,但是我提交的每一份报告都让我更加困惑。请原谅我的无知,但是如果有人能指出我禁止嘲笑的理由,我会非常感激。为什么我不应该嘲笑文件或路径

回答

3

我不确定有一个傻瓜证明的规则列表。这些事情总是有一定的知识和品味。教条通常不是一个好主意。

我投票结束这个问题,因为我认为很多是意见。

但是就这样说,我会做一个尝试。

单元测试应该是测试单个类,而不是类之间的交互。这些被称为集成测试。

如果你的对象调用其他远程对象,如服务,你应该嘲笑那些返回测试所需的数据。这个想法是服务和他们的客户也应该在他们自己的单元测试中单独测试。测试一个依赖于它们的类时,不需要重复这些。

在我看来,这个规则的一个例外是数据访问对象。在没有连接到远程数据库的情况下测试其中之一是没有意义的。您的测试需要证明代码的正确运行。对于数据访问对象,这需要数据库连接。这些应该写成事务性的:对数据库进行种子处理,执行测试,并将测试的操作反转。完成后数据库应该处于相同状态。

一旦您的数据访问对象被认证为正常工作,所有使用它们的客户端都应该嘲笑它们。无需重新测试。

你不应该在JVM中模拟类。

你问为什么关于文件或流尤其是 - 这是一个。采取或忽略它。

您不必测试JVM类,因为Sun/Oracle已经这样做了。你知道他们工作。你希望你的班级使用这些班级,因为一个失败的考试将暴露必要的文件不可用的事实。模拟不会告诉我,我忽略了将必需的文件放入我的CLASSPATH中。我想在测试过程中发现,而不是在生产中。

另一个原因是单元测试也是文档。这是一个为他人展示如何正确使用你的课程的现场演示。

+0

我还是不明白为什么我不应该能够模拟一个File对象。我应该只注入字符串和流,直接从文件或路径?当然,我也必须说服我的团队中的所有其他开发人员。 – Novaterata

+0

嘲笑文件究竟意味着什么?你为什么如此坚决?如果你的团队中的每个人都告诉你这不是一个好主意,那么你为什么如此着迷?我已经给了你一个有意义的例子 - 服务 - 这不是一个字符串或流。通过一切手段这样做。如果它适合你,那么很好。如果没有,承认这是浪费时间,继续前进。 – duffymo

+0

我想你误会,我会是一个说服我的团队的其他成员不嘲笑文件。我非常关注它,因为我的团队的其他成员将一个文件注入了一个类。这意味着getAbsolutePath的调用需要被模拟。 – Novaterata

2

在单元测试中,您必须测试您的代码是否正确。您可以剔除任何不是正在测试的直接代码的外部代码段。这是对单元测试的严格定义,它假设有另一种形式的测试称为集成测试,稍后将进行。在集成测试中,您可以测试代码如何与外部元素(如数据库或其他Web服务,网络或硬盘驱动器)交互。

如果我有一段与对象交互的代码(例如文件),并且我的代码对该文件做了3件事,那么在我的单元测试中,我将测试我的代码完成了这三件事情。

例如:

public void processFile(File f) { 
    if (f.exists()) { 
     //perform some tasks 
    } else { 
     //perform some other tasks 
    } 
} 

为了正确单元测试上面的代码我将运行的至少两个单元测试。一个用于测试文件是否存在,另一个用于测试我的代码在文件不存在时执行正确的操作。由于单元测试,恕我直言,只是测试我的代码,而不是做集成测试,那么它是完美的罚款,以模拟文件,以便您可以测试这种方法的两个分支。

在集成测试,那么你可以用一个真实的文件,测试您的应用程序将与周围的环境进行交互。

尝试的Mockito:

我不知道为什么jmockit不允许嘲笑File类。在Mockito中可以完成。下面的例子。

import java.io.File; 
import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.when; 

public class NewMain {  

    public static void main(String[] args) { 
     File f = mock(File.class); 
     when(f.exists()).thenReturn(true); 
     System.out.println("f.exists = " + f.exists()); 
    } 

} 
+0

这就是我的想法,但它不再支持jmockit。或者至少不认为值得修正错误。 – Novaterata

+0

添加了如何使用Mockito来模拟它的代码。 –

相关问题