sách gpt4 ai đã đi

java - 解决 JUnit 中的重复测试习语

In lại 作者:行者123 更新时间:2023-11-30 09:44:16 hai mươi bốn 4
mua khóa gpt4 Nike

我有 2 个案例对我来说似乎是同一个问题,尽管它们是完全不同的情况:

1) 我正在测试对象对数据库的读写。因为我每次都在清理和重建对象,写入测试需要读取以确认每个字段的写入,而读取测试是先写入,所以测试最终看起来是一样的。然而,我不想让接口(interface)中的主要方法未经测试。

2) 在更小的情况下,我正在为一个小数据对象测试一个 copy() 方法和一个 equals() 方法。 copy() 方法使用 equals() 来测试自身,而 equals() 方法正在针对副本进行测试。同样,测试是重复的。

我觉得我在这里遗漏了一些东西,一些方法来分离依赖而不创建大量额外的工作(比如让原始 JDBC 写入数据库等)有没有一种标准的方法来处理这种情况重复测试?

1 Câu trả lời

对我来说,这种测试是一种代码味道。问题始终是:此测试究竟测试了什么?对于这个测试,您信任什么,不信任什么?

对我来说,你不能同时信任 read() 和 write(),它们可能在同一个类中,由同一个人编写。因此,如果您通过调用 write() 来测试 read(),那么这不是一个好的测试,您测试的是 write() 和 read() 是否同步,而不是它们做了它们应该做的事情。

在第二个示例中,您正在测试复制和等价是否同步,同样的问题。

假设这是持久层的实现:

public class PersistenceLayer {
private Object object;

void write(Object object) {
this.object = object;
}

Object read(Long id) {
return object;
}
}

问题是,你的测试会通过这个持久层吗?但它显然不会做你想要的。它不靠近数据库。同样,如果您的读写共享 session /事务,您的测试会通过吗?在这种情况下,数据可能永远不会真正提交给数据库。它可能会在最后进行回滚。但是您的测试仍然会通过。

阅读您的描述,您正在测试当我调用 write() 然后调用 read() 时,我得到一个类似的对象。我对 write() 方法的期望是它将数据写入数据库。所以如果我正在测试那个,我需要检查那个。所以我必须有另一个 channel 可以用来测试读写。这通常以通过 JDBC 创建新连接并进行选择结束。

所以我的测试代码是

testWrite() {
write(o);
Object o2 = readByJdbc("SELECT * FROM table WHERE id = ?", o);
assertObjectsEqual(o, o2); // this needs to compare all values
}

testRead() {
write(o);
Object o2 = read(o.id);
Object o3 = readByJdbc("SELECT * FROM table WHERE id = ?", o);

assertObjectsEqual(o2, o3); // this needs to compare all values
}

testWrite() 写入数据库并确保数据通过打开 JDBC 连接并以这种方式读取(不同的 session ,不同的事务,即数据将在数据库中)写入数据库。

testRead() 写入数据库并比较通过持久层和通过jdbc 读取返回的两个对象。我正在复制对 write(o) 的调用,但它是可以接受的,因为我们知道当另一个测试被调用时 write 是否会起作用。我可以再写一个 writeByJdbc,但我得到的只是一个测试会失败,而不是两个。

事实上,根据您的偏执程度,您不需要比较 assertObjectsEqual() 中的所有值。例如,如果您使用的是 hibernate,您可以假设所有内容都已正确声明,并测试数据库中是否存在该行。我经常这样做,因为我相信 hibernate 。但在那种情况下,我需要测试我如何调用 hibernate ,如何定义对象。

jdbc 代码不需要很长很复杂,对于一个简单的选择,我只是创建一个列到值的映射列表:

private List<>> resultSetToListMap(ResultSet resultSet) throws SQLException {
int columnCount = resultSet.getMetaData().getColumnCount();
List<>> list = new ArrayList<>>();

while (resultSet.next()) {
Map map = new LinkedHashMap();

for (int i = 1; i <= columnCount; i++) {
map.put(resultSet.getMetaData().getColumnName(i), resultSet.getObject(i));
}

list.add(map);
}

return list;
}

这对于大多数测试来说已经足够了。

关于java - 解决 JUnit 中的重复测试习语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7988107/

hai mươi bốn 4 0
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com