package rewards.internal.account; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import rewards.internal.testdb.TestDataSourceFactory; import common.money.MonetaryAmount; import common.money.Percentage; import static org.junit.Assert.*; /** * Tests the JDBC account repository with a test data source to verify data access and relational-to-object mapping * behavior works as expected. */ @RunWith(JUnit4.class) public class JdbcAccountRepositoryTest { private JdbcAccountRepository repository; private DataSource dataSource; @Before public void setUp(){ dataSource = createTestDataSource(); repository = new JdbcAccountRepository(dataSource); } @Test public void testFindAccountByCreditCard() { Account account = repository.findByCreditCard("1234123412341234"); // assert the returned account contains what you expect given the state of the database assertNotNull("account should never be null", account); assertEquals("wrong entity id", Long.valueOf(0), account.getEntityId()); assertEquals("wrong account number", "123456789", account.getNumber()); assertEquals("wrong name", "Keith and Keri Donald", account.getName()); assertEquals("wrong beneficiary collection size", 2, account.getBeneficiaries().size()); Beneficiary b1 = account.getBeneficiary("Annabelle"); assertNotNull("Annabelle should be a beneficiary", b1); assertEquals("wrong savings", MonetaryAmount.valueOf("0.00"), b1.getSavings()); assertEquals("wrong allocation percentage", Percentage.valueOf("50%"), b1.getAllocationPercentage()); Beneficiary b2 = account.getBeneficiary("Corgan"); assertNotNull("Corgan should be a beneficiary", b2); assertEquals("wrong savings", MonetaryAmount.valueOf("0.00"), b2.getSavings()); assertEquals("wrong allocation percentage", Percentage.valueOf("50%"), b2.getAllocationPercentage()); } @Test public void testFindAccountByCreditCardNoAccount() { try { repository.findByCreditCard("bogus"); fail("Should've failed"); } catch (EmptyResultDataAccessException e) { // expected } } @Test public void testUpdateBeneficiaries() throws SQLException { Account account = repository.findByCreditCard("1234123412341234"); account.makeContribution(MonetaryAmount.valueOf("8.00")); repository.updateBeneficiaries(account); verifyBeneficiaryTableUpdated(); } private void verifyBeneficiaryTableUpdated() throws SQLException { String sql = "select SAVINGS from T_ACCOUNT_BENEFICIARY where NAME = ? and ACCOUNT_ID = ?"; PreparedStatement stmt = dataSource.getConnection().prepareStatement(sql); // assert Annabelle has $4.00 savings now stmt.setString(1, "Annabelle"); stmt.setLong(2, 0L); ResultSet rs = stmt.executeQuery(); rs.next(); assertEquals(MonetaryAmount.valueOf("4.00"), MonetaryAmount.valueOf(rs.getString(1))); // assert Corgan has $4.00 savings now stmt.setString(1, "Corgan"); stmt.setLong(2, 0L); rs = stmt.executeQuery(); rs.next(); assertEquals(MonetaryAmount.valueOf("4.00"), MonetaryAmount.valueOf(rs.getString(1))); } private DataSource createTestDataSource() { Resource schemaLocation = new ClassPathResource("/rewards/testdb/schema.sql"); Resource testDataLocation = new ClassPathResource("/rewards/testdb/test-data.sql"); return new TestDataSourceFactory("rewards", schemaLocation, testDataLocation).getDataSource(); } }