package org.testfun.jee; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.testfun.jee.real.SomeEntity; import org.testfun.jee.real.SomeDao; import org.testfun.jee.runner.SingletonEntityManager; import javax.annotation.Resource; import javax.ejb.EJB; import javax.ejb.SessionContext; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.script.ScriptException; import javax.sql.DataSource; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import java.security.Principal; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Collections; import java.util.List; import java.util.Set; import static org.junit.Assert.*; import static org.mockito.Mockito.when; @RunWith(EjbWithMockitoRunner.class) public class EjbWithMockitoRunnerSelfTest { @EJB private SomeDao someDao; @EJB private EjbLocal ejb; @Mock private MockEjbLocal mock; @Mock private NoInterfaceEjb noInterfaceEjb; @Mock private SessionContext sessionContext; @PersistenceContext private EntityManager entityManager; @Resource private DataSource dataSource; @Rule public ExpectedException exceptionRule = ExpectedException.none().handleAssertionErrors(); @Rule public ExpectedConstraintViolation violationThrown = ExpectedConstraintViolation.none(); @Test public void testEjbInjection() { // Test reading from DB using a DAO which uses JPA List<SomeEntity> all = someDao.getAll(); assertTrue("No entities were found", all.isEmpty()); // Test writing to DB using a DAO which uses JPA SomeEntity newSomeEntity = new SomeEntity(0, "name", "address"); assertEquals("Entity ID", newSomeEntity.getId(), 0); someDao.save(newSomeEntity); assertTrue("Entity ID > 0", newSomeEntity.getId() > 0); // write to DB second time to make sure transactions are not committed nor rolled back someDao.save(new SomeEntity(0, "name2", "another address")); assertEquals("Added two new providers", all.size() + 2, someDao.getAll().size()); // Make sure tests can fail (well... this test can't really guarantee this but it tries :D) String message = "Expected failure"; exceptionRule.expect(AssertionError.class); exceptionRule.expectMessage(message); fail(message); } @Test public void testEjbInjectionIntoEjb() throws ScriptException { assertEquals("7", ejb.realAnswer("(5+2).toString()")); assertEquals("10", ejb.realAnswer("((7-4)*3+1).toString()")); assertEquals("me", ejb.askSingleton()); } @Test public void testMockInjectionIntoEjb() { when(mock.mockAnswer("Whose motorcycle is this?")).thenReturn("It's a chopper baby."); when(mock.mockAnswer("Whose chopper is this?")).thenReturn("It's Zed's."); when(mock.mockAnswer("Who's Zed?")).thenReturn("Zed's dead baby, Zed's dead."); assertEquals("It's a chopper baby.", ejb.mockAnswer("Whose motorcycle is this?")); assertEquals("It's Zed's.", ejb.mockAnswer("Whose chopper is this?")); assertEquals("Zed's dead baby, Zed's dead.", ejb.mockAnswer("Who's Zed?")); } @Test public void testPersistenceInjection() throws SQLException { // Add a new provider using the entity manager directly (instead of an EJB) SomeEntity newSomeEntity = new SomeEntity(0, "name", "address"); entityManager.persist(newSomeEntity); assertTrue("Entity ID > 0", newSomeEntity.getId() > 0); // Use a JDBC connection to read the newly added provider, make sure calling close doesn't close the connection... int newId; try(Connection connection = dataSource.getConnection()){ try(Statement statement = connection.createStatement()) { try(ResultSet results = statement.executeQuery("SELECT id FROM some_entity WHERE name='name'")) { results.next(); newId = results.getInt(1); } } } assertEquals("Entity ID", newSomeEntity.getId(), newId); } @Test public void testNonAppExceptionRollsBack() { SomeEntity newSomeEntity = new SomeEntity(0, "name", "address"); someDao.save(newSomeEntity); try { ejb.nonAppException(); fail("Should have thrown an exception"); } catch (Exception e) { assertTrue("Transaction should have been rolled back", SingletonEntityManager.getInstance().getTransaction().getRollbackOnly()); } } @Test public void testAppException() { SomeEntity newSomeEntity = new SomeEntity(0, "name", "address"); someDao.save(newSomeEntity); try { ejb.appException(); fail("Should have thrown an exception"); } catch (Exception e) { assertFalse("Transaction should not be rolled back", SingletonEntityManager.getInstance().getTransaction().getRollbackOnly()); } } @Test public void testRollingBackAppException() { SomeEntity newSomeEntity = new SomeEntity(0, "name", "address"); someDao.save(newSomeEntity); try { ejb.appExceptionWithRollback(); fail("Should have thrown an exception"); } catch (Exception e) { assertTrue("Transaction should have been rolled back", SingletonEntityManager.getInstance().getTransaction().getRollbackOnly()); } } @Test public void testJavaxValidationExpectations() { violationThrown.expectViolation("javax.validation.ConstraintViolationException: Untested code violates the boys scout's rule!"); Set<ConstraintViolation<?>> violations = Collections.emptySet(); throw new ConstraintViolationException("javax.validation.ConstraintViolationException: Untested code violates the boys scout's rule!", violations); } @Test public void testHibernateValidationExpectations() { violationThrown.expectViolation("org.hibernate.exception.ConstraintViolationException: Untested code violates the boys scout's rule!"); throw new org.hibernate.exception.ConstraintViolationException("org.hibernate.exception.ConstraintViolationException: Untested code violates the boys scout's rule!", null, null); } @Test public void testMockOfNoInterfaceEjb() { when(noInterfaceEjb.returnSomething()).thenReturn("nothing"); assertEquals("nothing", ejb.returnFromNoInterfaceEjb()); } @Test public void testSessionContextMock() { when(sessionContext.getCallerPrincipal()).thenReturn(new Principal() { @Override public String getName() { return "kuki"; } }); assertEquals("kuki", ejb.getCurrentUser()); } }