简体   繁体   中英

Unit Test: @Inject not injecting service

here is my entity

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

and a 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;
    }
}

I also have DBConfig as

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 as

<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>  

My test looks like

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

and I get NullPointeException on userService

What am I missing?

Injection is handled by a Java EE Container in execution time. In particular and checking your piece of code, an EJB container would handle the injection of UserService since it is declared to be a Stateless bean. When you deploy your entire application a container is set and injection works fine. When executing unit tests (I guess using junit) none of the services are launched, and any @Injection will end up with the variable set to null, because no container will be launched either.

The idea is that unit tests should be only used for testing pieces of code independently of external ones like the one contained in other classes. However, in your case it looks like you want an integration test, so, you really need all services to be up since you want to check that an object is persisted in the database. For that, you need you need to launch also a container. A good way of doing that, is using Arquillian .

For instance, in your case, the test should be something like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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