Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java TDD-以与实现中使用的方法不同的方式检查方法的正确性_Java_Testing_Tdd - Fatal编程技术网

Java TDD-以与实现中使用的方法不同的方式检查方法的正确性

Java TDD-以与实现中使用的方法不同的方式检查方法的正确性,java,testing,tdd,Java,Testing,Tdd,我试图摆脱一种在我编写测试时经常发生的情况 一个示例场景是这样的:我有一个类Vagrant,它抽象了我在项目根目录中配置的一个Vagrant虚拟机(Vagrantfile)。在这个非常简单的例子中,这个类只有一个方法start()和一个方法isRunning(),或者可能是getStatus(),这没有任何区别 测试应如下所示: @Test public void daemonIsSuccessfullyInstalled() { Vagrant vm = new Vagrant();

我试图摆脱一种在我编写测试时经常发生的情况

一个示例场景是这样的:我有一个类
Vagrant
,它抽象了我在项目根目录中配置的一个Vagrant虚拟机(
Vagrantfile
)。在这个非常简单的例子中,这个类只有一个方法
start()
和一个方法
isRunning()
,或者可能是
getStatus()
,这没有任何区别

测试应如下所示:

@Test
public void daemonIsSuccessfullyInstalled()
{
    Vagrant vm = new Vagrant();
    vm.start();

    // todo: here I want to test that the Vagrant vm is actually running.

    assertTrue(vm.isRunning());
    // or
    assertEquals(vm.getStatus(), "running");
}
使用
VM.start()
启动VM后,我想检查VM是否正在实际运行。为此,我只需运行
Runtime.getRuntime().exec(“vagrant status”)
并用正则表达式解析输出以提取状态

但是,这就是我计划在实现方法
getStatus()
isRunning()
时要做的。但是,在测试中使用相同的技术来检查
start()
方法的正确性有意义吗

换句话说,我的问题是,我将使用相同的代码(或相同的逻辑,不管用于实现它的实际代码是什么)来检查方法
start()
是否与我用于实现方法
isRunning()
的方法一样正常工作。现在我该如何检查代码是否正确?我是否应该确信这个逻辑是正确的,也就是说,我应该放弃测试某些方法,而是假设它们是正确的

或者,我应该努力找到另一种解耦的方法来检查VM是否正在运行(可能是查看
ps
或其他什么),以避免在测试和实现中使用相同的代码吗?在我看来,这就像编写一个使用
+
运算符计算和的方法,然后使用相同的
+
运算符检查方法的输出是否正确。如果
+
操作员被窃听怎么办

多谢各位


编辑:忘了提到考试题目指的是什么。我想测试一个守护程序是否在系统启动时在vm内部正确启动,在我看来,“vm已启动”测试应该只是一个小的辅助测试,但它产生了这个问题。顺便说一句,也许我应该在这个特定问题中为测试方法使用不同的名称。另外,感谢Carl Manaster的建议。

开始使用TDD原则工作的人经常会遇到这个问题

当测试像您这样的东西(执行特定于运行时的东西)、建立数据库连接或最常见的文件i/o时,就会出现此问题

但真正的问题不是如何测试,而是测试这些方法

单元测试旨在快速运行。非常快。系统应该是独立的,不应该执行任何i/o操作

单元测试应测试算法、数据处理等,不应执行i/o

但您可能想知道如何测试i/o操作?不是单元测试,而是集成测试——但这是一个独立的故事

然而,你应该测试你的
Vagrant
类,而不是你的
Vagrant
类,让人困惑但请容忍我

你的
Vagrant
类应该像一个代理。它处理vm和发送到运行时的命令。Bur不应该送他们!要将您的
Vagrant
类发送给他们,可以使用专用类,如
CommandRunner
。此类应该是可注入的(关键字:DependencyInjection)。这也意味着
CommandRunner
应该是一个接口(这不是必需的,但会使事情变得更简单!),基本实现可以
UnixCommandRunner
(您可以看到,这也允许在windows机器上运行命令!)

这让你可以模仿(如果你以前没听说过的话,用谷歌搜索),这基本上就是用一个真正的
CommandRunner
来交换,它什么都不做(除了记录对其方法的调用等)。但是您可以通过让
MockCommandRunner
存储方法调用来检查命令是否已运行,您可以在测试中检索方法调用


我希望这能给你一个基本的想法,关于如何在单元测试中处理I/o的东西

想想你真正在测试什么,你真正想测试什么。测试名称可能非常有用。您将其称为“daemonIsSuccessfullyInstalled”,但您正在尝试在启动后测试其状态是否为“running”。试着把你的测试方法命名为“应该”:“应该在开始时运行”,也许。在实现方面—您没有测试
isRunning()
是如何实现的,只是在对象启动后返回true。最简单的实现():
返回true。现在,你知道这不起作用,所以你需要多锻炼一下。可能在调用
start
之前放置一个断言,以确保它尚未运行


您并不是在真正测试
isRunning
的功能。您可能希望,作为一个单独的单元测试,该测试可能包含模拟。这个测试只是关于
start
和'isRunning'之间的交互作用。

谢谢你的建议。我修复了这个误导性的方法名..问题实际上是关于如何测试vm是否启动。关于您关于在
start()
之前测试vm未运行的建议,这不会再次引发同样的问题吗?
isRunning()
start()
之前和
true
之后返回
false
是否足以确保
start()
按要求工作?这不是简单地将问题转移到
isRunning()
如何工作的内部吗?(也许这正是你在最后一段中所说的…:在这种情况下,我的问题变成了如何测试这种方法。)是的,这就是最后一段的内容