首页 > 解决方案 > JUnit 测试单独成功,但一起执行时会失败并导致错误?

问题描述

我有三个 JUnit 测试,如下所示。如果单独执行这些测试,即注释掉另外两个测试并只执行一个,这些测试都会成功。

但是,如果我执行所有三个未注释的测试,则“testOrderDatabaseReturnsOrdersCorrectly”会产生错误,并且“testOrderDatabaseRemovesOrdersCorrectly”会失败。

我真的不明白为什么会这样。我在每次测试之前都使用@Before 进行设置,所以所有三个测试的条件应该相同吗?为什么他们中的一些人在单独工作时会失败?

@Before
public void setup()
{
    sys = new OrderSystem();
    sys.getDb().clearDb();
}


@Test
public void testOrderDatabaseAddsOrders()
{
    sys.getDb().clearDb();
    sys.createOrder(25);
    assertEquals(sys.getDb().getDbArrayList().size(), 1);

    sys.createOrder(30);
    assertEquals(sys.getDb().getDbArrayList().size(), 2);

    sys.createOrder(35);
    assertEquals(sys.getDb().getDbArrayList().size(), 3);
}


@Test
public void testOrderDatabaseRemovesOrdersCorrectly()
{
    sys.createOrder(25);
    assertEquals(sys.getDb().getDbArrayList().size(), 1);
    sys.removeOrder("BRICK1");
    assertEquals(sys.getDb().getDbArrayList().size(), 0);
}

@Test
public void testOrderDatabaseReturnsOrdersCorrectly()
{
    System.out.println("Size of db: " + sys.getDb().getDbArrayList().size());
    sys.createOrder(25);
    System.out.println("Size of db: " + sys.getDb().getDbArrayList().size());
    BrickOrder o = sys.getOrder("BRICK1");
    assertEquals(o.getNumberOfBricks(), 25);
}

标签: javajunit

解决方案


但是,如果我执行所有三个未注释的测试,则“testOrderDatabaseReturnsOrdersCorrectly”会产生错误,并且“testOrderDatabaseRemovesOrdersCorrectly”会失败。

您的问题很可能是当运行下一个测试方法并且它们发生冲突时,其中一种测试方法的结果没有被清除。也许您正在使用像 H2 这样的内存数据库,即使您正在调用它也没有被完全清除sys.getDb().clearDb();

有几种方法可以验证这一点:

  • 首先放入一条System.out.println()消息setup()以确保在每个方法之前调用它。
  • 在您的测试方法开始时,在您的数据库中进行查找以查看是否有结果来验证clearDb()所做的事情。我怀疑你会发现它没有完全工作。
  • 更改测试方法以使用非重叠表或使用非重叠数据以查看是否有效。例如,在每个测试方法中创建一个int orderNumber字段并++对其进行操作,以确保您使用的是新订单。这当然是一种解决方法。最好理解为什么 clear 没有做你想做的事。

如何解决这个问题是一个更复杂的问题,取决于实际支持您的db. 也许您的clearDb()方法中存在一些错误。我之所以提到 H2,是因为即使您设置了一个全新的数据库连接,旧的连接也不会被破坏并且会被重用。如果它是一个 SQL 数据库,那么完全删除表并重新创建它们甚至会迫使像 H2 这样的持久内存数据库清除其内容。

希望这可以帮助。


推荐阅读