Как и кто должен вводить PersiSceCtextext при запуске тестов через Джерси / Гризли?

StackOverflow https://stackoverflow.com/questions/3814621

Вопрос

У меня есть этот класс (сочетание JAX-RS / Jersey и JPA / Hibernate):

public class Factory {
  @PersistenceContext(unitName = "abc")
  EntityManager em;
  @Path("/{id}")
  @GET
  public String read(@PathParam("id") int i) {
    return em.find(Employee.class, i).getName();
  }
}

Это тест на единицу:

public class FactoryTest extends JerseyTest {
  public FactoryTest() throws Exception {
    super("com.XXX");
  }
  @Test
  public void testReadingWorks() {
    String name = resource().path("/1").get(String.class);
    assert(name.length() > 0);
  }
}

Здесь все хорошо, кроме одного этого: em является NULL внутри read(). Отказ Похоже, Grizzly (я использую этот сервер вместе с тестовой структурой Джерси) не впрыскивает PersistenceContext. Отказ Что я здесь делаю не так?

Это было полезно?

Решение

Здесь все хорошо, кроме одного этого: EM NULL внутри прочитанного (). Похоже, Grizzly (я использую этот сервер вместе с тестовой структурой Джерси) не впрыскивает PersiSceCtextext. Что я здесь делаю не так?

  1. Я не уверен, что Гризли предлагает инъекцию.
  2. Я не уверен, что впрыск поддерживается в «любой» ресурс Джерси в любом случае (Пол Сандос, кажется, подразумевает, что это должно быть в эта нить Но я не мог найти четкие доказательства этого претензии).

Итак, для моих знаний, самое простое решение было бы ввести EntityManager в EJB 3.1 Системный сеансный боб (SLSB), который может быть подвергнут напрямую в качестве ресурсов для отдыха (путем аннотации его аннотациями Jax-RS).

Другой вариант сделает ресурс JAX-RS управляемый боб И использовать CDI для инъекций. Это подход TOTD # 124: с использованием CDI + JPA с JAX-RS и JAX-WS.

В обоих случаях я думаю, что вам нужно будет использовать встроенный контейнер Glassfish в качестве контейнера для ваших тестов для джерси.

Ресурсы

Другие советы

Я нашел решение для com.sun.jersey / Джерси-Гризли2 версия 1.x.. Отказ Я реализовал обычай ИнъекционныеProvider.. Отказ Следующий код взят из Статья Oracle:

import javax.ejb.EJB;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.ws.rs.ext.Provider;

import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;

@Provider
public class EJBProvider implements InjectableProvider<EJB, Type> {

    public Scope getScope() {
        return Scope.Singleton;
    }

    public Injectable getInjectable(ComponentContext cc, EJB ejb, Type t) {
        if (!(t instanceof Class)) return null;

        try {
            Class c = (Class)t;        
            Context ic = new InitialContext();

            final Object o = ic.lookup(c.getName());

            return new Injectable<Object>() {
                public Object getValue(HttpContext c) {
                    return o;
                }                    
            };            
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

Мне пришлось слегка адаптировать его, чтобы соответствовать моей среде. Также обратите внимание, что поставщик должен быть в том же пакете, что и ваш класс обслуживания, в противном случае он не будет забран (не говорит о том, что в статье).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top