这是我的实体
@Entity
public class User {
@Id
private String id;
private String externalUserId;
private String email;
private String clientId;
private String clientSecret;
private boolean active;
public User(@Nonnull final String externalUserId, @Nonnull final String email,
@Nonnull final String clientId, @Nonnull final String clientSecret, final boolean active) {
id = UUID.randomUUID().toString();
this.externalUserId = externalUserId;
this.email = email;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.active = active;
}
}
和UserService
import javax.annotation.Nonnull;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceUnit;
@Stateless
public class UserService {
@PersistenceUnit
private EntityManager entityManager;
@Nonnull
public User createUser(@Nonnull final User user) {
entityManager.persist(user);
return user;
}
}
我还有DBConfig
import javax.annotation.sql.DataSourceDefinition;
import javax.ejb.Stateless;
@DataSourceDefinition(
name = "java:app/oauth/testDB",
className = "org.h2.jdbcx.JdbcDataSource",
url = "jdbc:h2:mem:test"
)
@Stateless
public class DBConfig {
}
test/src/main/resources/persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="testDB" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.self.oauth.persistence.entities.User</class>
</persistence-unit>
</persistence>
我的测试看起来像
public class UserTest {
@Inject
private UserService userService;
@Test
public void testUser() {
final User user = new User(UUID.randomUUID().toString(), "test@test.com", "clientId", "clientSecret", true);
userService.createUser(user);
assertTrue(true);
}
}
我在NullPointeException
userService
我错过了什么?
答案 0 :(得分:1)
注入由Java EE容器在执行时处理。特别是在检查您的代码时,EJB容器将处理UserService的注入,因为它被声明为无状态bean。部署整个应用程序时,将设置容器并且注入工作正常。当执行单元测试时(我猜使用junit)没有启动任何服务,并且任何@Injection最终都会将变量设置为null,因为也不会启动任何容器。
这个想法是单元测试应该只用于测试代码片段,而不像其他类中包含的外部代码。但是,在您的情况下,您似乎需要集成测试,因此,您确实需要所有服务,因为您要检查对象是否在数据库中持久存在。为此,您需要启动一个容器。这样做的好方法是使用Arquillian。
例如,在您的情况下,测试应该是这样的:
package org.arquillian.example;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(Arquillian.class)
public class UserTest{
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClass(UserService.class)
.addClass(User.class)
.addClass(DBConfig.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Inject
private UserService userService;
@Test
public void testUser() {
final User user = new User(UUID.randomUUID().toString(), "test@test.com", "clientId", "clientSecret", true);
userService.createUser(user);
assertTrue(true);
}
}