JUnit与基于命令行的程序

时间:2018-03-30 14:18:34

标签: java junit junit4

我对JUnit有疑问。

我有一个从命令行运行的java程序。它接受两个txt文件(String args [])的名称作为输入,然后处理第一个文件中的数据并将结果输出到第二个文件。

我现在处于为我的程序编写测试用例的阶段。我决定使用JUnit框架。

我的问题是:

  1. 为了测试main方法,我决定用一个字符串数组来调用它。这是最优化的方式吗?
  2. 现在,我想测试其他功能,其中大多数都是打印特定输出,如何从控制台读取它以断言预期输出已被打印?
  3. 有时候,我期待抓住一个例外。因为它已被捕获,我无法使用@Test(预期的Exception.class)。还有另一种方法可以检查异常是否已被抛出并同时被捕获?
  4. 对不起我的一长串问题!

    感谢。

3 个答案:

答案 0 :(得分:0)

  

为了测试main方法,我决定使用一个字符串数组来调用它。这是最优化的方式吗?

没有其他办法。你如何测试一个方法,期望一个字符串数组而不调用它并传递一个字符串数组?也就是说,主要方法应该非常非常小,并委托其他方法使事情变得更容易。像

这样的东西
public static void main(String[] args) throws IOException {
    new Program(new FileInputStream(args[0]), 
                new FileOuptutStream(args[1]), 
                System.out)
        .run();
}

这样,你需要真正测试的是run()的{​​{1}}方法(以及它可能使用的其他类和方法)。

  

如何从控制台读取该信息以断言预期输出已被打印?

在上面的主要方法中,看看如何将System.out传递给程序?程序应该写入的位置,而不是直接写入Program

由于您可以在测试中创建System.out并将其传递给任何PrintStream,因此您可以选择将PrintStream传递给内存数据结构,而不是传递Program。例如:System.out,然后检查字节数组的内容是什么。

或者,您可以定义更高级别的抽象,而不是将new PrintStream(someByteArrayOutputStream)传递给PrintStream构造函数,而不是

Program

这将允许在您的测试中传递任何模拟实现,并且,我的主要方法,将实际打印的实现传递给public interface Output { public void println(String s); }

System.out
  

有时候,我期待抓住一个例外

然后测试它在抛出异常时正在做/返回正确的事情。让我们举一个例子:

new Program(..., System.out::println)

您可以通过首先传递一个有效的String来测试此方法,并检查该方法是否返回正确的Instant,然后传递一个无效的String,并检查该方法是否返回null。

答案 1 :(得分:0)

我建议使用一些单元测试框架。 Mockito可以是一个很好的起点。 http://site.mockito.org/ 你可以在那里嘲笑FileReaders和Writers。 您还可以期望使用您的参数调用某些方法。

答案 2 :(得分:0)

单元测试实例化我们应用程序的一小部分,并独立于其他部分验证其行为。但是,这需要对代码进行组织,以便您实际可以实例化我们应用程序的一小部分,并独立于其他部分验证其行为。

现在,问题:

  1. 是的,没关系。使用字符串数组调用main方法并检查它是否调用它应该调用的任何内容。

  2. 有很多方法可以做到这一点。例如,您应该设置或传递将用于输出的编写器或打印流,而不是打印到System.out或类似物。然后,在测试中,您可以实例化并传递一个测试拥有的编写器。你的功能很乐意输出到这位作家,最后你可以查看作者的内容来验证写的是什么。

  3. 如果您可以通过参数提出抛出异常,那就没问题了。在这种情况下,只需检查方法是否正确。如果强制异常并不容易,请将可能异常抛出的部分提取到单独的方法中。然后,您可以模拟您的对象并强制从该方法中抛出异常。