我写了一个类,它从控制台获取输入并在 main 方法中获取参数。 main 方法为不同的控制台输入调用不同的方法,并为不同的参数调用不同的函数。所以我想通过模拟文件中的这些输入来用 Junit 测试这个主要方法。我该怎么做? junit中有没有特殊规定测试类的main方法?
原文由 user2719152 发布,翻译遵循 CC BY-SA 4.0 许可协议
我写了一个类,它从控制台获取输入并在 main 方法中获取参数。 main 方法为不同的控制台输入调用不同的方法,并为不同的参数调用不同的函数。所以我想通过模拟文件中的这些输入来用 Junit 测试这个主要方法。我该怎么做? junit中有没有特殊规定测试类的main方法?
原文由 user2719152 发布,翻译遵循 CC BY-SA 4.0 许可协议
IMO 测试 main 方法的最佳方法是让 main 方法除了设置世界并启动它之外什么都不做。这样,一个简单的集成测试就可以给出“世界是否已经建立”的答案。
然后所有其他问题变得更容易回答。
main 方法为不同的控制台输入调用不同的方法,并为不同的参数调用不同的函数。
它不应该,它应该调用 someService.somemethod(args)
。该服务像其他任何服务一样接受测试。
所以我想通过模拟文件中的这些输入来用 Junit 测试这个主要方法。我该怎么做?
注入某种形式的伪造品或使用 TemporaryFolder JUnit 规则。
原文由 Michael Lloyd Lee mlk 发布,翻译遵循 CC BY-SA 3.0 许可协议
15 回答8.2k 阅读
8 回答6k 阅读
1 回答4.1k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.2k 阅读
2 回答3.9k 阅读
1 回答2.2k 阅读✓ 已解决
要提供来自文件的输入,请创建
FileInputStream
并将其设置为System.in
流。您可能希望在 main 方法完成后将原始设置恢复原状,以确保以后使用它的任何东西仍然有效(其他测试,JUnit 本身……)这是一个例子:
在您的实际代码中,您将希望处理任何 IOExceptions 并使用比文件的完整路径更好的东西(通过类加载器获取它),但这给了您一般的想法。
编辑:
几年后有了更多的智慧,我不得不同意 Michael Lloyd Lee mlk 的回答,认为这是更好的方法,如果可能的话应该首选什么。在包含您的
main
方法(或什至是一个单独的类)的类中,应该有一个接受任意InputStream
和参数数组的方法。它可以是一个静态方法。main
方法然后使用System.in
流作为参数调用它。或者,您可以使用一个带有接受参数数组的构造函数的类来创建一个正确配置的实例,然后在其上调用一个接受
InputStream
的实例方法,如下所示:最适合要求和程序设计的。在这两种情况下,您最终都会得到一些可以使用从文件中获得的
InputStream
进行单元测试的东西。对Main.start
执行简单静态方法调用的测试,或创建 Bootstrapper 实例然后调用其start
方法的测试。现在您的测试不再依赖于System.in
流。 main 方法做的工作很少,而且非常简单,您无需单独测试即可相信它的正确性。在某些时候,一段代码变得如此微不足道,以至于测试它等同于不信任编译器。这些主要方法中的问题很快就会变得明显,因为它是您知道将始终被调用的一种方法。一个 main 方法做的太多或者太复杂通常表明代码缺乏模块化。我保留原来的答案是因为它确实提供了一个解决方案,以防您真的无法通过使用
System.in
并测试 main 方法。这就是我一开始写它的原因,因为我不能确定提问者的限制。有时有人只是想直接回答他们的确切问题,因为没有更好的方法;您不允许更改代码,或者重构它需要付出太多努力并且没有预算,或者使用了一些硬编码为使用系统流等的库。请注意,原始答案无论如何都不那么可靠。如果测试并行而不是顺序运行,换出系统流可能会导致意外和不一致的故障。