我试图学习有关JUnit和TDD的更多信息,但是我遇到了一些测试用例之间的耦合问题。
当我为特定数据类型的API编写测试用例时,比如说Deque<T>
,如何限制测试用例之间的耦合?例如,如果我正在为insertFirst(T item)
方法编写一个测试用例,那么似乎很容易假设我应该能够在正确初始化的对象上调用该方法之后断言两件事:
Deque
对象的大小应该增加一个T removeFirst()
方法,它应该返回对我在初始调用中插入的对象的引用。 但是,这在我的至少两个测试用例之间造成了不良耦合,其中一个测试用例的通过取决于另一种API方法的正确实现。例如,为了使该测试用例通过,我需要一个正确的实现来检查Deque
中的项目数以及删除项目。如果我出于任何原因对这些方法之一的测试都不正确或不完整,则对insertFirst
方法的测试将自动成为可疑。
避免这种情况的最佳做法是什么?我编写测试用例的方法是否有些错误?
参考方案
在为一个方法编写测试时,必须假定类的其余部分正常工作。如果您不做这个假设,那么唯一的结论就是每个班级进行一次单独的大规模测试。那不是我们要做的。
您可以假设该类的其他部分正常工作,因为这些其他部分也将进行测试,以确保它们的正确性。
如果某个部分无法正常工作,则测试将失败,并向您显示某些错误。
一旦测试套件的测试失败,就必须修复一个错误。您不再可以做任何假设。
例:
您有一个仅使用三种方法的简单列表实现:
您有三个测试:
insert
:
insert
项目(Act)count
等于1(声明)remove
:
insert
项的实例(排列)remove
项目(Act)count
等于0(声明)count
:
insert
n项的实例(排列)count
(Act)count
等于n(声明)现在,如果以上任何测试失败,则无法确定班级中单个成员的正确性:
remove
,因为没有要删除的内容。 insert
和count
是否正常工作,因为如果三个成员中的任何一个均不能正常工作,则第二项测试将失败。 失败的测试告诉您一些信息:
根据失败的测试,您通常可以推断出错误的出处。
示例:如果仅第二项测试失败,但第一项或第三项测试没有失败,则错误很可能是remove
方法。
我已经用Java编写了REST端点。应用程序中有c#代码使用RestClient调用这些端点。我正在考虑为这些编写单元测试。只是想知道什么是最好的方法? Moq框架或NUNIT还是其他?有任何想法吗?谢谢。 参考方案 如果要在Java中测试REST端点,则可以使用Mockito(https://site.mockito.org/)之类的模拟框架来模拟所需的任…
Java:线程池如何将线程映射到可运行对象 - java试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …
JAVA:字节码和二进制有什么区别? - javajava字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…
java:继承 - java有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…
Java:BigInteger,如何通过OutputStream编写它 - java我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…