java - 我应该在单元测试时从正在测试的类中调用方法吗?

标签 java unit-testing junit

我有一个数据库助手类,它执行插入、删除、保存、连接等操作,我正在为此编写测试。但是,当我编写测试用例时,它应该独立于测试类吗?

应该是这样的: 1-)

@Test
public void testDelete() throws SQLException {
    // Given
    String dateStr = "09-May-2016";
    String word = "testWord";
    derbyDb.save(dateStr, word, 9);
    derbyDb.save(dateStr, word, 11);

    // When
    assertEquals(2, derbyDb.contain(dateStr, word));
    derbyDb.delete();

    // then
    assertEquals(0, derbyDb.contain(dateStr, word));
}

(你看这里,我用了'save'方法。)

2-)

@Test
public void testDelete() throws SQLException {
    // Given
    String dateStr = "09-May-2016";
    String word = "testWord";
    PreparedStatement insertemp = conn
                .prepareStatement("insert into " + tableName + "(PUBLISHDATE,WORD,FREQUENCY) values(?,?,?)");
        insertemp.setString(1, dateStr);
        insertemp.setString(2, word);
        insertemp.setInt(3, frequency);
        insertemp.executeUpdate();

    // When
    assertEquals(2, derbyDb.contain(dateStr, word));
    derbyDb.delete();

    // then
    assertEquals(0, derbyDb.contain(dateStr, word));
}

哪个是正确的或更好的?或者测试单元是否应该独立于其他功能?

编辑:在删除前添加 AssertEquals。

EDIT-2:在第二个选项中,应该只有一个方法是“删除”并且将独立于类中的其他方法。因此应该有一个查询而不是包含方法。

最佳答案

假设您也自己测试 save 方法,我会使用 1,以便您的 delete 测试不会在您更改内部实现时中断保存以使用其他机制。

或者,您可以在 @Before 方法中插入要删除的记录,以便您在实际测试中只需使用 delete,即可很清楚它在方法中测试的是什么。

无论哪种情况,您都应该在删除之前 assertEquals(2, derbyDb.contain(dateStr, word));,这样您就知道 delete 是原因为什么之后为零。


Google 的 Testing on the Toilet 博客有一篇与此相关的帖子:"Test Behavior, Not Implementation" .

Tests that are independent of implementation details are easier to maintain since they don't need to be changed each time you make a change to the implementation. They're also easier to understand since they basically act as code samples that show all the different ways your class's methods can be used, so even someone who's not familiar with the implementation should usually be able to read through the tests to understand how to use the class.

在测试中复制数据库级逻辑就是测试实现。您可能需要进行 future 的更改,例如:

  • 重命名数据库表和列;
  • 更改 derbyDb 类以使用其他一些底层存储 - 也许您想要它的内存中实现,或者您无法使用 JDBC 连接的东西。

如果您采用了第二种方法,则必须去修复测试以及被测代码。

如果您采用了第一种方法,则不会。测试中的一切都“正常工作”——或者没有,但你知道这是一个错误的实现,而不是一个错误的测试。

关于java - 我应该在单元测试时从正在测试的类中调用方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38369589/

相关文章:

angular - 如何在 Angular 单元测试中模拟函数中的服务调用?

android - 在 `runBlockingTest` 测试 Room 的事务查询

java - 类名异常

java - Spring JUnit 测试未加载完整的应用程序上下文

java - 由于 IllegalState 异常,Android TestRunner 失败

Java:ArrayBlockingQueue 与 LinkedBlockingQueue

java - JSF + 支持 bean : How to detect when the application first load

java - 使用Keycloak获取id_token

java - 如何使用扫描仪捕获txt文件中的字符串?

C++ lambda 测试拦截器/模拟