java - 单元测试可以使用被测类的方法进行测试设置吗
问题描述
我有一个有 6 个方法的类 Inventory。我应该在一个名为 InventoryTEST 的测试类中为这 6 个方法中的每一个实现测试。类对象是一个哈希图。
这是该类的方法
/**
* Return the number of Records.
*/
public int size() { }
/**
* Return a copy of the record for a given Video.
*/
public Record get(VideoObj v) { }
/**
* Return a copy of the records as a collection.
* Neither the underlying collection, nor the actual records are returned.
*/
public Collection toCollection() {}
/**
* Add or remove copies of a video from the inventory.
* If a video record is not already present (and change is
* positive), a record is created.
* If a record is already present, <code>numOwned</code> is
* modified using <code>change</code>.
* If <code>change</code> brings the number of copies to be less
* than one, the record is removed from the inventory.
* @param video the video to be added.
* @param change the number of copies to add (or remove if negative).
* @throws IllegalArgumentException if video null or change is zero
* @postcondition changes the record for the video
*/
public void addNumOwned(VideoObj video, int change) {
}
/**
* Check out a video.
* @param video the video to be checked out.
* @throws IllegalArgumentException if video has no record or numOut
* equals numOwned.
* @postcondition changes the record for the video
*/
public void checkOut(VideoObj video) {
}
/**
* Check in a video.
* @param video the video to be checked in.
* @throws IllegalArgumentException if video has no record or numOut
* non-positive.
* @postcondition changes the record for the video
*/
public void checkIn(VideoObj video) {
}
/**
* Remove all records from the inventory.
* @postcondition <code>size() == 0</code>
*/
public void clear() {
}
现在为了测试这些方法,我需要创建一个包含一些记录的对象。我可以做到这一点的一种方法是调用默认构造函数,它将给我一个空的哈希图,然后调用 addNumOwned 将记录添加到哈希图中。我可以做到这一点的另一种方法是创建一个重载的构造函数,它可以在创建时在哈希图中添加记录。
我在第一种方法中看到的问题是 addNumOwned 是在测试类中测试的方法(和单元)。因此,如果这个单元出现故障,所有其他单元也会出现故障。一个单元测试是否应该怀疑另一个单元测试的失败?
我想如果我必须对构造函数进行单元测试,同样的参数也会成立。但是,我没有对构造函数进行单元测试。
解决方案
如果您正在为一个类编写一套测试,那么您的一些测试的设置代码可以使用该类的方法。事实上,避免这样做几乎是不可能的。
如果您希望您的测试全面,您将需要测试您的类的构造函数。但是当然,作为设置阶段的一部分,您类的方法的所有测试都必须首先创建您的类的对象。
public ThingTest // We have a class named Thing we want to test, this is its unit tests
{
@Test
public void testIncrement() // Test of the Thing.increment method
{
// Set up:
var thing = new Thing(); // Using part of the Thing class in the set up phase!
// Exercise:
thing.increment();
// Verify:
assertEquals(1, thing.count());
}
...
我猜您很担心,因为您希望安排您的测试,以便您正在测试的代码中的错误仅导致一次测试失败,因此调试测试失败很容易。那是一个理想,值得为之奋斗,但也只是一个理想。在实践中,某些类型的错误和测试不可能这么简单。
您可以通过确保进行全面的测试以及自下而上的测试来缓解这一困难。也就是说,如果测试的设置阶段依赖于正确运行的特定 mutator 或构造函数,则您必须对该 mutator 或构造函数进行单元测试。
对于复杂的代码,您可以考虑使用 Java 级别assert
的语句(我的偏好)或JUnit 假设来检查测试的设置阶段是否已正确完成,然后再执行您正在测试的方法。然后,您将不会遇到难以调试的测试失败,而是会AssertionError
更AssumptionViolatedException
清楚TestAbortedException
地指出问题的原因。
@Test
public void testIncrement()
{
var thing = new Thing();
assert thing.count() == 0;
thing.increment();
// Verify:
assertEquals(1, thing.count());
}
...
推荐阅读
- java - 如何存储随机变量并为游戏打印?(java)
- django - 在服务器上添加夹具时出现反序列化错误(loaddata)
- java - 为什么很多类的方法和接口都没有在JSR文档中定义
- ruby-on-rails - capistrano 部署失败 db:migrate 发布升级到焦点 fossa 后
- java - 尝试在 switch 语句中使用类
- android - 如何与其他应用程序共享(ACTION_VIEW)文件?
- node.js - 为什么我的 Electron 应用程序中没有导入 contextBridge?
- adaptive-cards - 自适应卡片模板是否可以在 Composer 中使用?
- javascript - 我应该如何动态更新firebase文档
- python - 将元组列表(来自 itertools)转换为文本文件中的单词列表,Python