繁体   English   中英

黄瓜步骤-使用持久性上下文测试EJB服务

[英]Cucumber steps - testing an EJB service with a persistence context

我有一个使用@PersistenceContextEntityManager的无状态EJB,我正在编写一个黄瓜步骤定义类,该类使用此Service根据提供的条件执行测试查找用户的步骤。

所以举个例子

@Stateless
public class UserService {

    @PersistenceContext
    private EntityManager em;

    public void add(String userName) {
        User user = new User(userName);
        em.persist(user);
    }    

    public List<User> findByName(String userName) {
        return em.createQuery("Select u from User as u WHERE u.name LIKE :userName").setParameter("userName", userName).getResultList();
    }

}

还有一个功能文件,看起来像

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'

和步骤定义类

 public class SearchStepsDefinitions {

   private List<User> userList = new ArrayList<>();
   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)); 
   }

}

现在我了解到,由于服务是EJB,因此通过@PersistenceContext注入EntityManager

我的问题是在步骤定义中我应该如何处理这种依赖性? 我应该嘲笑它,并注入该模仿到UserService ,还是应该UserService有一个引领者EntityManager和使用EntityManagerFactory创建一个在SearchStepsDefinitions

所以换句话说

@Stateless
public class UserService {

    @PersistenceContext
    private EntityManager em;

    public void add(String userName) {
        User user = new User(userName);
        em.persist(user);
    }    

    public List<User> 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;
    }

}

然后,步骤定义将是这样

public class SearchStepsDefinitions {

   private List<User> userList = new ArrayList<>();

   @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)); 
   }

}

或这个

public class SearchStepsDefinitions {

   private List<User> userList = new ArrayList<>();

   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)); 
   }

}

本质上,我正在尝试与本示例相同,但是我没有使用Spring

也许另一个选择是不将服务作为EJB并将@Inject注入其中

public class UserService {

    @Inject
    private EntityManager em;

    public void add(String userName) {
        User user = new User(userName);
        em.persist(user);
    }    

    public List<User> findByName(String userName) {
        return em.createQuery("Select u from User as u WHERE u.name LIKE :userName").setParameter("userName", userName).getResultList();
    }

}

然后这些步骤看起来像

 public class SearchStepsDefinitions {

   private List<User> userList = new ArrayList<>();

   @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)); 
   }

}

我不确定这些方法的优缺点吗?

经过大量的挖掘,我发现我需要使用一个EJBContainer,然后Steps类现在看起来像这样

 public class SearchStepsDefinitions {

   private Context context;
   private EJBContainer container;

   private List<User> userList = new ArrayList<>();

   private UserService userService;

   @cucumber.api.java.Before
   public void setup() {
       ejbContainer = EJBContainer.createEJBContainer();
       context = ejbContainer.getContext();

       userService = (UserService) context.lookup("java:global/classes/UserService");
   }

   @cucumber.api.java.After
   public void teardown() {
       ejbContainer.close();
   }

   @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)); 
   }

}

需要做的另一件事是pom中的ejb容器。 我用玻璃鱼,有这种依赖性。

<dependency>
    <groupId>org.glassfish.main.extras</groupId>
    <artifactId>glassfish-embedded-all</artifactId>
    <version>4.1</version>
</dependency>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM