0

I need your help to understand a unit (method) behaviors within a unit test class shown below.

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

The method shown above tells me that the exception will be thrown if the account is not found

However the 2nd test ( updateNotExistedAccount) method shown below shows that it's expected that the method above (updateAccount ) should throw an exception to past the test. However, newAccount is already initialized /created within the createNewAccount so it exists already. So I assume that the updateNotExistedAccount will failed the test (because updateAccount won't throw exceptions in that case ), however updateNotExistedAccount passed.

    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);
        }

Is it wrong if I assume updateNotExistedAccount will fail the test?

2 Answers2

1

Seems like the data are persisted from one test to another. Try to clean the data after each test.

@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());
}

For your test to be complete, and to test the update, I would do something like this:

@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);
}

UPDATE
Consider also that @Before and @After runs respectively before and after each single test. @BeforeClass and @AfterClass respectively before and after all tests.

With the use of these 4 methods you can start always the test with the desired dataset, and after the test clean everything as it were.
Please see: Difference between @Before, @BeforeClass, @BeforeEach and @BeforeAll

Ermal
  • 441
  • 5
  • 19
  • Thanks. For some reason I thought @Before will run only once. – Plain_Dude_Sleeping_Alone Nov 23 '19 at 17:00
  • 1
    Yes, please consider also that `@Before` and `@After` runs respectively before and after each single test. `@BeforeClass` and `@AfterClass` respectively before and after all tests. (updated the answer for more visibility) Have a nice evening. – Ermal Nov 23 '19 at 17:14
1

To properly check need to look at your newAccount code as well as what all you are Mocking.

  • Check your @Before method as that will run before every @Test
  • Check if which test is running first when you run your suite