package com.smartitengineering.cms.repo.dao.impl.tx;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.smartitengineering.cms.repo.dao.tx.Transaction;
import com.smartitengineering.cms.repo.dao.tx.TransactionCompletionEvent;
import com.smartitengineering.cms.repo.dao.tx.TransactionCompletionListener;
import com.smartitengineering.cms.repo.dao.tx.TransactionManager;
import junit.framework.Assert;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.Before;
import org.junit.Test;
/**
*
* @author imyousuf
*/
public class TransactionManagerImplTest {
private Mockery mockery;
private TransactionFactory factory;
private TransactionInMemoryCache memCache;
@Before
public void setup() {
mockery = new Mockery();
factory = mockery.mock(TransactionFactory.class);
memCache = mockery.mock(TransactionInMemoryCache.class);
}
@Test
public void testNonExistingTransaction() {
Injector injector = initializeInjector();
final TransactionManager manager = injector.getInstance(TransactionManager.class);
mockery.checking(new Expectations() {
{
}
});
Assert.assertNull(manager.getCurrentTransaction());
mockery.assertIsSatisfied();
}
@Test
public void testBeginTransaction() {
Injector injector = initializeInjector();
final TransactionManager manager = injector.getInstance(TransactionManager.class);
mockery.checking(new Expectations() {
{
exactly(1).of(factory).createTransaction(true);
final Transaction txMock = mockery.mock(Transaction.class);
will(returnValue(txMock));
exactly(1).of(txMock).addTransactionCompletionListener((TransactionCompletionListener) manager);
}
});
manager.beginTransaction();
mockery.assertIsSatisfied();
}
@Test
public void testGetCurrentTransactionForSingleTxOnAThread() {
Injector injector = initializeInjector();
final TransactionManager manager = injector.getInstance(TransactionManager.class);
mockery.checking(new Expectations() {
{
exactly(1).of(factory).createTransaction(true);
final Transaction txMock = mockery.mock(Transaction.class);
will(returnValue(txMock));
exactly(1).of(txMock).addTransactionCompletionListener((TransactionCompletionListener) manager);
}
});
Transaction tx = manager.beginTransaction();
Assert.assertSame(tx, manager.getCurrentTransaction());
mockery.assertIsSatisfied();
}
@Test
public void testGetCurrentTransactionForMultiTxOnAThread() {
Injector injector = initializeInjector();
final TransactionManager manager = injector.getInstance(TransactionManager.class);
mockery.checking(new Expectations() {
{
exactly(1).of(factory).createTransaction(true);
final Transaction txMock1 = mockery.mock(Transaction.class, "Tx1");
will(returnValue(txMock1));
exactly(1).of(txMock1).addTransactionCompletionListener((TransactionCompletionListener) manager);
exactly(1).of(factory).createTransaction(true);
final Transaction txMock2 = mockery.mock(Transaction.class, "Tx2");
will(returnValue(txMock2));
exactly(1).of(txMock2).addTransactionCompletionListener((TransactionCompletionListener) manager);
}
});
Transaction tx1 = manager.beginTransaction();
Assert.assertSame(tx1, manager.getCurrentTransaction());
Transaction tx2 = manager.beginTransaction();
Assert.assertSame(tx2, manager.getCurrentTransaction());
mockery.assertIsSatisfied();
}
@Test
public void testGetCurrentTransactionWithTransactionCompletionInProperOrder() {
Injector injector = initializeInjector();
final TransactionManager manager = injector.getInstance(TransactionManager.class);
final TransactionCompletionListener listener = (TransactionCompletionListener) manager;
mockery.checking(new Expectations() {
{
exactly(1).of(factory).createTransaction(true);
final Transaction txMock1 = mockery.mock(Transaction.class, "Tx1");
will(returnValue(txMock1));
exactly(1).of(txMock1).addTransactionCompletionListener(listener);
exactly(1).of(txMock1).getId();
will(returnValue("1"));
exactly(1).of(memCache).removeTransactionReferences("1");
exactly(1).of(factory).createTransaction(true);
final Transaction txMock2 = mockery.mock(Transaction.class, "Tx2");
will(returnValue(txMock2));
exactly(1).of(txMock2).getId();
will(returnValue("2"));
exactly(1).of(txMock2).addTransactionCompletionListener(listener);
exactly(1).of(memCache).removeTransactionReferences("2");
}
});
Transaction tx1 = manager.beginTransaction();
Assert.assertSame(tx1, manager.getCurrentTransaction());
Transaction tx2 = manager.beginTransaction();
Assert.assertSame(tx2, manager.getCurrentTransaction());
TransactionCompletionEvent event2 = new TransactionCompletionEvent(TransactionCompletionEvent.CompletionEvent.COMMIT,
true, tx2);
listener.transactionComplete(event2);
Assert.assertSame(tx1, manager.getCurrentTransaction());
TransactionCompletionEvent event1 = new TransactionCompletionEvent(TransactionCompletionEvent.CompletionEvent.COMMIT,
true, tx1);
listener.transactionComplete(event1);
Assert.assertNull(manager.getCurrentTransaction());
mockery.assertIsSatisfied();
}
@Test
public void testGetCurrentTransactionWithTransactionCompletionInInproperOrder() {
Injector injector = initializeInjector();
final TransactionManager manager = injector.getInstance(TransactionManager.class);
final TransactionCompletionListener listener = (TransactionCompletionListener) manager;
mockery.checking(new Expectations() {
{
exactly(1).of(factory).createTransaction(true);
final Transaction txMock1 = mockery.mock(Transaction.class, "Tx1");
will(returnValue(txMock1));
exactly(2).of(txMock1).getId();
will(returnValue("1"));
exactly(1).of(txMock1).addTransactionCompletionListener(listener);
exactly(1).of(memCache).removeTransactionReferences("1");
exactly(1).of(factory).createTransaction(true);
final Transaction txMock2 = mockery.mock(Transaction.class, "Tx2");
will(returnValue(txMock2));
exactly(1).of(txMock2).getId();
will(returnValue("2"));
exactly(1).of(txMock2).addTransactionCompletionListener(listener);
exactly(1).of(memCache).removeTransactionReferences("2");
}
});
Transaction tx1 = manager.beginTransaction();
Assert.assertSame(tx1, manager.getCurrentTransaction());
Transaction tx2 = manager.beginTransaction();
Assert.assertSame(tx2, manager.getCurrentTransaction());
TransactionCompletionEvent event1 = new TransactionCompletionEvent(TransactionCompletionEvent.CompletionEvent.COMMIT,
true, tx1);
listener.transactionComplete(event1);
Assert.assertSame(tx2, manager.getCurrentTransaction());
TransactionCompletionEvent event2 = new TransactionCompletionEvent(TransactionCompletionEvent.CompletionEvent.COMMIT,
true, tx2);
listener.transactionComplete(event2);
Assert.assertNull(manager.getCurrentTransaction());
mockery.assertIsSatisfied();
}
private Injector initializeInjector() {
final Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(TransactionManager.class).to(TransactionManagerImpl.class);
bind(TransactionFactory.class).toInstance(factory);
bind(TransactionInMemoryCache.class).toInstance(memCache);
}
});
return injector;
}
}