Как разрешить "Вы не начали контекст Objectify" в JUnit?

У меня есть тестовый код Objectify, запущенный в JUnit, и я получаю эту ошибку:

java.lang.IllegalStateException: You have not started an Objectify context. You are probably missing the ObjectifyFilter. If you are not running in the context of an http request, see the ObjectifyService.run() method.
    at com.googlecode.objectify.ObjectifyService.ofy(ObjectifyService.java:44)
    at com.googlecode.objectify.impl.ref.LiveRef.<init>(LiveRef.java:31)
    at com.googlecode.objectify.Ref.create(Ref.java:26)
    at com.googlecode.objectify.Ref.create(Ref.java:32)
    at com.netbase.followerdownloader.repository.DownloadTaskRepositoryImpl.create(DownloadTaskRepositoryImpl.java:35)
    at com.netbase.followerdownloader.repository.DownloadTaskRepositoryImplTest.setUp(DownloadTaskRepositoryImplTest.java:45)

Как это разрешить для тестового кода?

Ответ 1

Джефф Шницер ответил на это здесь: https://groups.google.com/forum/#!topic/objectify-appengine/8HinahG7irg. Эта ссылка указывает на https://groups.google.com/forum/#!topic/objectify-appengine/O4FHC_i7EGk, где Джефф предлагает следующее быстрое и грязное обходное решение:

  • My @BeforeMethod запускает контекст объектива (ObjectifyService.begin())

  • My @AfterMethod закрывает контекст объектива

Джефф предлагает использовать вместо ObjectifyService.run(), но признает, что он больше работает.

Вот как выглядит моя реализация:

public class DownloadTaskRepositoryImplTest {
    // maximum eventual consistency (see https://cloud.google.com/appengine/docs/java/tools/localunittesting)
    private final LocalServiceTestHelper helper =
        new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()
            .setDefaultHighRepJobPolicyUnappliedJobPercentage(100));

    private Closeable closeable;

    @Before
    public void setUp() {
        helper.setUp();
        ObjectifyRegistrar.registerDataModel();
        closeable = ObjectifyService.begin();
    }

    @After
    public void tearDown() {
        closeable.close();

        helper.tearDown();
    }

Ответ 2

У меня также была эта проблема, и я заметил, что я не добавил ObjectifyFilter в свой web.xml

<filter>
    <filter-name>ObjectifyFilter</filter-name>
    <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ObjectifyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Мне также пришлось включить Objectify и guava jars в мой каталог WEB-INF > lib и включить их в мой путь сборки.

Ответ 3

Я столкнулся с той же ошибкой, и это решение работало для меня

У меня есть приложение, основанное на Endpoints, которое использует Objectify. Когда я оставляю его по умолчанию/автоматическое масштабирование, все отлично работает. Однако, когда я включаю базовое масштабирование, при выполнении метода конечной точки я получаю следующее исключение:

[INFO] java.lang.IllegalStateException: You have not started an Objectify context. You are probably missing the ObjectifyFilter. If you are not running in the context of an http request, see the ObjectifyService.run() method.
[INFO]  at com.googlecode.objectify.ObjectifyService.ofy(ObjectifyService.java:44)
[INFO]  at com.myco.myapp.dao.datastore.OfyService.ofy(OfyService.java:62)

Хорошей новостью является то, что это происходит, когда вы включаете RequestDispatcher поддержка в файле web.xml. Я думаю, что это документация вопрос, тогда, но я не знал, согласятся ли все, если бы я отредактировал Вики-страница напрямую. Вот предлагаемая запись web.xml, которая работала для меня:

   <filter>
    <filter-name>ObjectifyFilter</filter-name>
    <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ObjectifyFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

Ответ 4

Улучшая michael-osofsky ответ, я добавляю это в мой вспомогательный класс

public static void registerDataModel() {
    try {
        factory().register(Profile.class);
    } catch (Exception e){
        e.printStackTrace();
    }
}

и remplace

ObjectifyRegistrar.registerDataModel();

для этого

OfyService.registerDataModel();

OfyService.java

public static void registerDataModel() {
    try {
        factory().register(Profile.class);
    } catch (Exception e){
        e.printStackTrace();
    }
}