title: Cucumber steps - testing an EJB service with a persistence context
body: <p>I have a stateless EJB that uses <code>@PersistenceContext</code> with a <code>EntityManager</code>, I'm writing a cucumber step definitions class that uses this Service to perform steps in testing finding users based upon supplied criteria.</p>
  
  <p>So for example</p>
  
  <pre><code>@Stateless
  public class UserService {
  
      @PersistenceContext
      private EntityManager em;
  
      public void add(String userName) {
          User user = new User(userName);
          em.persist(user);
      }    
  
      public List&lt;User&gt; findByName(String userName) {
          return em.createQuery("Select u from User as u WHERE u.name LIKE :userName").setParameter("userName", userName).getResultList();
      }
  
  }
  </code></pre>
  
  <p>And a feature file that looks something like</p>
  
  <pre><code>Feature: Search
  
      Given a user with the name 'Jason Statham'
          And another user with the name 'Bill Gates'
          And another user with the name 'Larry Page'
      When the customer searches for a user with the name 'Jason'
      Then 1 users should have been found
          And User 1 should have a name of 'Jason Statham'
  </code></pre>
  
  <p>And a steps definition class </p>
  
  <pre><code> public class SearchStepsDefinitions {
  
     private List&lt;User&gt; userList = new ArrayList&lt;&gt;();
     private UserService userService = new UserService();
  
     @Given(value = ".+user with the name '(.+)'$")
     public void a_user_with_the_name(final String userName) {
         userService.add(userName);
     }
  
     @When(value = "^the customer searches for a user with the name '(.+)'$")
     public void the_customer_searches_for_a_user_with_the_name(final String name) {
         userList = userService.findByName(name); 
     }
  
     @Then(value = "(\\d+) users should have been found$")
     public void users_should_have_been_found(final int userCount) {
         assertThat(userList.size(), equalTo(userCount));
     }
  
     @Then(value = "User (\\d+) should have a name of '(.+)'$")
     public void should_have_a_name_of(final int position, final String name) {
         assertThat(userList.get(position - 1).getName(), equalTo(name)); 
     }
  
  }
  </code></pre>
  
  <p>Now I understand that as the Service is an EJB the <code>EntityManager</code> is injected
  via the <code>@PersistenceContext</code>.</p>
  
  <p>My question is in the steps definition how should I be dealing with this dependency? Should I be mocking it and injecting this mock into the <code>UserService</code>, or should the <code>UserService</code> have a setter for the <code>EntityManager</code> and use a <code>EntityManagerFactory</code> to create one in the <code>SearchStepsDefinitions</code>?</p>
  
  <p>So in other words</p>
  
  <pre><code>@Stateless
  public class UserService {
  
      @PersistenceContext
      private EntityManager em;
  
      public void add(String userName) {
          User user = new User(userName);
          em.persist(user);
      }    
  
      public List&lt;User&gt; findByName(String userName) {
          return em.createQuery("Select u from User as u WHERE u.name LIKE :userName").setParameter("userName", userName).getResultList();
      }
  
      public void setEm(EntityManager em) {
          this.em = em;
      }
  
  }
  </code></pre>
  
  <p>Then the steps definition would either be this</p>
  
  <pre><code>public class SearchStepsDefinitions {
  
     private List&lt;User&gt; userList = new ArrayList&lt;&gt;();
  
     @Mock
     private EntityManager em;       
  
     @Inject
     @InjectMocks
     private UserService userService;
  
     @Given(value = ".+user with the name '(.+)'$")
     public void a_user_with_the_name(final String userName) {
         userService.add(userName);
     }
  
     @When(value = "^the customer searches for a user with the name '(.+)'$")
     public void the_customer_searches_for_a_user_with_the_name(final String name) {
         userList = userService.findByName(name); 
     }
  
     @Then(value = "(\\d+) users should have been found$")
     public void users_should_have_been_found(final int userCount) {
         assertThat(userList.size(), equalTo(userCount));
     }
  
     @Then(value = "User (\\d+) should have a name of '(.+)'$")
     public void should_have_a_name_of(final int position, final String name) {
         assertThat(userList.get(position - 1).getName(), equalTo(name)); 
     }
  
  }
  </code></pre>
  
  <p>Or this</p>
  
  <pre><code>public class SearchStepsDefinitions {
  
     private List&lt;User&gt; userList = new ArrayList&lt;&gt;();
  
     private UserService userService = new UserService();
  
     @Before
     public void setup() {
         userService.setEm(Persistence.createEntityManagerFactory("punit").createEntityManager());
     }
  
     @Given(value = ".+user with the name '(.+)'$")
     public void a_user_with_the_name(final String userName) {
         userService.add(userName);
     }
  
     @When(value = "^the customer searches for a user with the name '(.+)'$")
     public void the_customer_searches_for_a_user_with_the_name(final String name) {
         userList = userService.findByName(name); 
     }
  
     @Then(value = "(\\d+) users should have been found$")
     public void users_should_have_been_found(final int userCount) {
         assertThat(userList.size(), equalTo(userCount));
     }
  
     @Then(value = "User (\\d+) should have a name of '(.+)'$")
     public void should_have_a_name_of(final int position, final String name) {
         assertThat(userList.get(position - 1).getName(), equalTo(name)); 
     }
  
  }
  </code></pre>
  
  <p>Essentially I'm trying to do the same as <a href="https://github.com/cucumber/cucumber-jvm/blob/master/examples/spring-txn/src/test/java/cucumber/examples/spring/txn/SeeMessagesStepdefs.java" rel="nofollow">this example</a> but I'm not using Spring</p>
  
  <p>Or perhaps another option would be to not have the service as an EJB and <code>@Inject</code> the EntityManager into it</p>
  
  <pre><code>public class UserService {
  
      @Inject
      private EntityManager em;
  
      public void add(String userName) {
          User user = new User(userName);
          em.persist(user);
      }    
  
      public List&lt;User&gt; findByName(String userName) {
          return em.createQuery("Select u from User as u WHERE u.name LIKE :userName").setParameter("userName", userName).getResultList();
      }
  
  }
  </code></pre>
  
  <p>And then the steps would look like</p>
  
  <pre><code> public class SearchStepsDefinitions {
  
     private List&lt;User&gt; userList = new ArrayList&lt;&gt;();
  
     @Inject
     private UserService userService;
  
     @Given(value = ".+user with the name '(.+)'$")
     public void a_user_with_the_name(final String userName) {
         userService.add(userName);
     }
  
     @When(value = "^the customer searches for a user with the name '(.+)'$")
     public void the_customer_searches_for_a_user_with_the_name(final String name) {
         userList = userService.findByName(name); 
     }
  
     @Then(value = "(\\d+) users should have been found$")
     public void users_should_have_been_found(final int userCount) {
         assertThat(userList.size(), equalTo(userCount));
     }
  
     @Then(value = "User (\\d+) should have a name of '(.+)'$")
     public void should_have_a_name_of(final int position, final String name) {
         assertThat(userList.get(position - 1).getName(), equalTo(name)); 
     }
  
  }
  </code></pre>
  
  <p>I'm not really sure of the pro's and con's of these approaches?</p>