我有一个无状态 EJB,它使用 @PersistenceContext
与 EntityManager
,我正在编写一个 cucumber 步骤定义类,该类使用此服务来执行根据提供的条件测试查找用户的步骤。
举个例子
@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,所以 EntityManager
被注入(inject)
通过@PersistenceContext
.
我的问题是在步骤定义中我应该如何处理这种依赖性?我应该模拟它并将这个模拟注入(inject) UserService
,或者应该UserService
有一个 EntityManager
的 setter 并使用 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));
}
}
本质上我正在尝试做与 this example 相同的事情但我没有使用 Spring
或者也许另一种选择是不将服务作为 EJB 和 @Inject
将 EntityManager 添加到其中
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.xml 中的 ejb 容器。我使用 glassfish,具有这种依赖性。
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>4.1</version>
</dependency>
关于java - Cucumber 步骤 - 使用持久性上下文测试 EJB 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31030380/