【问题标题】:Why does this test pass?为什么这个测试会通过?
【发布时间】:2019-11-23 15:56:11
【问题描述】:

我需要您的帮助来理解单元测试类中的单元(方法)行为,如下所示。

public void updateAccount(Account account) {
 if (!accountExists(account.getAccountNo())) { 
throw new AccountNotFoundException();
} 
accounts.put(account.getAccountNo(), account); 
}

上面显示的方法告诉我如果找不到账号就会抛出异常

但是,下面显示的第二个测试 (updateNotExistedAccount) 方法表明,上面的方法 (updateAccount) 应该抛出异常以通过测试。但是,newAccount 已经在 createNewAccount 中初始化/创建,因此它已经存在。所以我假设updateNotExistedAccount 会通过测试(因为updateAccount 在这种情况下不会抛出异常),但是updateNotExistedAccount 通过了。

    public class InMemoryAccountDaoTests {
    private static final String NEW_ACCOUNT_NO = "998";
     private Account newAccount; 
    private InMemoryAccountDao accountDao;

   @Before 
    public void init() { 

     newAccount = new Account(NEW_ACCOUNT_NO, 200); 
    accountDao = new InMemoryAccountDao(); 
    }

        @Test
         public void createNewAccount() { 
         accountDao.createAccount(newAccount);
        assertEquals(accountDao.findAccount(NEW_ACCOUNT_NO), newAccount); }



        @Test(expected = AccountNotFoundException.class)
         public void updateNotExistedAccount() { accountDao.updateAccount(newAccount);
        }

如果我认为updateNotExistedAccount 会通过测试,这有错吗?

【问题讨论】:

    标签: java unit-testing junit tdd hamcrest


    【解决方案1】:

    似乎数据从一个测试持续到另一个测试。 尝试在每次测试后清理数据。

    @After
    public void clean(){
        // this method will be run after each single @Test method
        // you can use this to clean all resoruces after a test. in your case for example
        accountDao.deleteById(newAccount.getId());
    }
    

    为了完成您的测试并测试更新,我会这样做:

    @Test
    public void updateExistingAccount() {
        accountDao.createAccount(newAccount);
        dbAccount = accountDao.findAccount(newAccount.getId);
        dbAccount.setName("");
        dbAccount.setSurname("");
        // etc...
        accountDao.updateAccount(dbAccount);
        dbAccountUpdated = accountDao.findAccount(newAccount.getId);
        assertEquals(accountDao.findAccount(dbAccountUpdated.getId()), dbAccount);
    }
    

    更新
    还要考虑@Before@After 分别在每次测试之前和之后运行。 @BeforeClass@AfterClass 分别在所有测试之前和之后。

    通过使用这 4 种方法,您可以始终使用所需的数据集开始测试,并在测试后按原样清理所有内容。
    请参见: Difference between @Before, @BeforeClass, @BeforeEach and @BeforeAll

    【讨论】:

    • 谢谢。出于某种原因,我认为@Before 只会运行一次。
    • 是的,还请注意@Before@After 在每次测试之前和之后分别运行。 @BeforeClass@AfterClass 分别在所有测试之前和之后。 (更新了答案以获得更多可见性)祝你有个愉快的夜晚。
    【解决方案2】:

    要正确检查需要查看您的newAccount 代码以及您在模拟什么。

    • 检查您的@Before 方法,因为它会在每个@Test 之前运行
    • 在运行套件时检查是否先运行哪个测试

    【讨论】:

      猜你喜欢
      • 2018-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多