package hirondelle.fish.main.member;
import java.io.FileNotFoundException;
import javax.servlet.ServletException;
import junit.framework.*;
import hirondelle.web4j.security.SafeText;
import hirondelle.web4j.database.DAOException;
import hirondelle.web4j.database.DuplicateException;
import hirondelle.web4j.model.Id;
import hirondelle.web4j.model.ModelCtorException;
import hirondelle.fish.test.TESTAll;
import hirondelle.fish.test.doubles.FakeDAOBehavior;
import static hirondelle.fish.test.doubles.FakeDAOBehavior.DbOperation;
import static hirondelle.fish.test.doubles.FakeDAOBehavior.DbOperationResult;
/**
JUnit tests for {@link MemberDAO} and {@link MemberDAOFake}.
<P>To run this class, the <b>classpath must contain the database driver</b>.
See {@link TESTAll#initControllerIfNeeded()} as well.
<P>These unit tests exercise the basic sanity of add/fetch/change/delete operations.
There are other operations defined in {@link MemberDAO}, but they aren't tested by this
class. Transactions are not used to rollback the changes to the database.
<P>When all tests succeed, any records created by these tests are automatically deleted towards the end.
If the tests <em>fail</em>, however, then it's usually necessary to <em>manually</em> delete
records created by these tests.
*/
public class TESTMemberDAO extends TestCase {
/** Initialize the environment and run the test cases. */
public static void main(String args[]) throws ServletException, FileNotFoundException {
TESTAll.setRootDirectory();
TESTAll.initControllerIfNeeded();
String[] testCaseName = { TESTMemberDAO.class.getName() };
junit.textui.TestRunner.main(testCaseName);
}
public TESTMemberDAO(String aName) {
super(aName);
}
// TEST CASES //
/** Test the real DAO. */
public void testRealDAO() throws DAOException, ModelCtorException {
MemberDAO realDAO = new MemberDAO();
testForSuccess(realDAO);
}
/** Test the fake DAO, without configuring explicit failures for any of its operations. */
public void testFakeDAO() throws DAOException, ModelCtorException {
MemberDAO fakeDAO = new MemberDAOFake();
testForSuccess(fakeDAO);
}
/**
Test the fake DAO, with configuring explicit failures for all its operations.
One of the advantages of using
*/
public void testFakeDAOFailure() throws DAOException, ModelCtorException {
FakeDAOBehavior.setBehavior(DbOperation.FetchForChange, DbOperationResult.ThrowDAOException);
FakeDAOBehavior.setBehavior(DbOperation.Add, DbOperationResult.ThrowDuplicateException);
FakeDAOBehavior.setBehavior(DbOperation.Change, DbOperationResult.ThrowDuplicateException);
FakeDAOBehavior.setBehavior(DbOperation.Delete, DbOperationResult.ThrowDAOException);
FakeDAOBehavior.setBehavior(DbOperation.List, DbOperationResult.ThrowDAOException);
MemberDAO fakeDAO = new MemberDAOFake();
testFakeForFailures(fakeDAO);
}
//PRIVATE//
private void testForSuccess(MemberDAO aMemberDAO) throws DAOException, ModelCtorException {
//add
Member memberOne = new Member(null, new SafeText("Bob Smithers"), Boolean.TRUE, Id.from("4") );
Id idOne = aMemberDAO.add(memberOne);
//fetch
Member memberOneFetched = aMemberDAO.fetch(idOne);
assertNotNull(memberOneFetched);
assertTrue(memberOneFetched.equals(memberOne));
//log("memberOneFetched: " + memberOneFetched);
//change
Member memberTwo = new Member(idOne, new SafeText("Bob Smitherspoon"), Boolean.TRUE, Id.from("4") );
aMemberDAO.change(memberTwo);
Member memberTwoFetched = aMemberDAO.fetch(idOne);
assertNotNull(memberTwoFetched);
assertTrue(! memberTwoFetched.equals(memberOne));
assertTrue(memberTwoFetched.equals(memberTwo));
//delete
aMemberDAO.delete(idOne);
memberTwoFetched = aMemberDAO.fetch(idOne);
assertNull(memberTwoFetched);
}
private void testFakeForFailures(MemberDAO aMemberDAO) throws ModelCtorException, DAOException {
//add
Member memberOne = new Member(null, new SafeText("Bob Smithers"), Boolean.TRUE, Id.from("4") );
try {
Id id = aMemberDAO.add(memberOne);
fail("Should have failed.");
}
catch(DuplicateException ex){
//should happen - do nothing
}
//change
Member memberTwo = new Member(Id.from("13"), new SafeText("Bob Smitherspoon"), Boolean.TRUE, Id.from("4") );
try {
aMemberDAO.change(memberTwo);
fail("Should have failed.");
}
catch(DuplicateException ex){
//should happen - do nothing
}
//delete
try {
aMemberDAO.delete(Id.from("13"));
fail("Should have failed");
}
catch(DAOException ex){
//should happen - do nothing
}
//list
try {
aMemberDAO.list();
fail("Should have failed");
}
catch (DAOException ex){
//should happen - do nothing
}
//fetch
try {
aMemberDAO.fetch(Id.from("13"));
fail("Should have failed");
}
catch (DAOException ex){
//should happen - do nothing
}
}
}