Как использовать тесты JUnit с Spring Roo?(Проблемы с EntityManager) - PullRequest
6 голосов
/ 19 июля 2010

Я пытаюсь написать тест JUnit для проекта Spring Roo. Если мой тест требует использования классов сущностей, я получаю следующее исключение:

java.lang.IllegalStateException: Entity manager has not been injected 
(is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)

JAR Spring Aspect выглядит правильно настроенным. В частности, в файле pom.xml есть следующее:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>${spring.version}</version>
</dependency>

и

<plugin>
  <configuration>
  <outxml>true</outxml>
  <aspectLibraries>
    <aspectLibrary>
      <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
    </aspectLibrary>
  </aspectLibraries>
  <source>1.6</source>
  <target>1.6</target>
  </configuration>
</plugin>

и классы, которые используют классы сущностей, работают нормально, когда не вызываются из теста JUnit. Любая идея, как я могу настроить вещи так, чтобы менеджер сущностей вводился из теста JUnit?

Вот мой тестовый класс (более или менее):

public class ServiceExampleTest {

  @Test
  public void testFoo() {
    FooService fs = new FooServiceImpl();
    Set<Foo> foos = fs.getFoos();
  }
}

Этого достаточно, чтобы бросить исключение. Класс FooServiceImpl возвращает Set of Foo, где Foo является классом сущности. Метод getFoos() работает, когда приложение выполняется обычным способом. Проблема возникает только в контексте модульных тестов.

Ответы [ 7 ]

6 голосов
/ 11 ноября 2010

Понзао правильно.Я могу использовать всю магию пружинного впрыска, если мой тестовый класс расширяет AbstractJunit4SpringContextTests.

например

@ContextConfiguration(locations = { "/META-INF/spring/applicationContext.xml" })
public class SelfRegistrationTest extends AbstractJUnit4SpringContextTests {
3 голосов
/ 14 ноября 2012

Ваш класс модульного теста должен иметь аннотацию @MockStaticEntityMethods.

Просто хотел добавить более подробную информацию к ответу выше, @migue, так как мне потребовалось некоторое время, чтобы выяснить, как получитьэто на работу.Сайт http://java.dzone.com/articles/mock-static-methods-using-spring-aspects действительно помог мне получить ответ ниже.

Вот что я сделал, чтобы внедрить менеджер сущностей через тестовый класс.Сначала аннотируйте свой тестовый класс с помощью @MockStaticEntityMethods и создайте класс MockEntityManager (это класс, который просто реализует интерфейс EntityManager).

Затем вы можете сделать следующее в своем тестовом классе ServiceExampleTest:

@Test
public void testFoo() {
  // call the static method that gets called by the method being tested in order to
  // "record" it and then set the expected response when it is replayed during the test
  Foo.entityManager();
  MockEntityManager expectedEntityManager = new MockEntityManager() {
    // TODO override what method you need to return whatever object you test needs
  };
  AnnotationDrivenStaticEntityMockingControl.expectReturn(expectedEntityManager);

  FooService fs = new FooServiceImpl();
  Set<Foo> foos = fs.getFoos();
}

Это означает, что когда вы вызываете fs.getFoos (), AnnotationDrivenStaticEntityMockingControl будет внедрять ваш фиктивный менеджер сущностей, поскольку Foo.entityManager () является статическим методом.

Также обратите внимание, что , если fs.getFoos() вызывает другие статические методы классов Entity, такие как Foo и Bar, они также должны быть указаны как часть этого тестового примера.

Так, например, у Foo был статический метод поиска с именем "getAllBars (Long fooId)"который вызывается при вызове fs.getFoos (), тогда вам нужно будет сделать следующее, чтобы заставить AnnotationDrivenStaticEntityMockingControl работать.

@Test
public void testFoo() {
  // call the static method that gets called by the method being tested in order to
  // "record" it and then set the expected response when it is replayed during the test
  Foo.entityManager();
  MockEntityManager expectedEntityManager = new MockEntityManager() {
    // TODO override what method you need to return whatever object you test needs
  };
  AnnotationDrivenStaticEntityMockingControl.expectReturn(expectedEntityManager);

  // call the static method that gets called by the method being tested in order to
  // "record" it and then set the expected response when it is replayed during the test
  Long fooId = 1L;
  Foo.findAllBars(fooId);
  List<Bars> expectedBars = new ArrayList<Bar>();
  expectedBars.add(new Bar(1));
  expectedBars.add(new Bar(2));
  AnnotationDrivenStaticEntityMockingControl.expectReturn(expectedBars);

  FooService fs = new FooServiceImpl();
  Set<Foo> foos = fs.getFoos();
}

Помните, что AnnotationDrivenStaticEntityMockingControl должен быть в том же порядке, что и fs.getFoos () вызывает его статические методы.

3 голосов
/ 08 ноября 2010

Это невероятно раздражающая проблема с Spring Roo, и я не нашел официального решения для.

Но ... вот два обходных пути:

  • Скопируйте банку аспектов Spring в свой проект, затем добавьте его в свой проект AspectJ Aspect Path
  • Используйте Maven для запуска юнит-тестов (и пропустите зеленую полосу :()

Для первого варианта Щелкните правой кнопкой мыши по своему проекту и выберите Свойства-> Сборка AspectJ -> Вкладка «Путь аспекта».

1 голос
/ 16 ноября 2010

Ваш класс модульного теста должен иметь аннотацию @MockStaticEntityMethods.

0 голосов
/ 13 сентября 2015

Это сработало для меня с Spring Roo:

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

import com.jitter.finance.analyzer.domain.Address;

@ContextConfiguration(locations = { "classpath*:/META-INF/spring/applicationContext*.xml"})
public class EmTest extends AbstractJUnit4SpringContextTests {

    @Test
    public void checkEm(){
        Address a = new Address();
        a.setName("Primo");
        a.persist();

        Address b = new Address();
        b.setName("Secondo");
        b.persist();

        for(Address ad : Address.findAllAddresses()){
            System.out.println(ad.getName());
            assertEquals(ad.getName().charAt(ad.getName().length()-1), 'o');
        }
    }
}

С классом Address вроде этого:

import org.springframework.roo.addon.javabean.annotations.RooJavaBean;
import org.springframework.roo.addon.javabean.annotations.RooToString;
import org.springframework.roo.addon.jpa.annotations.activerecord.RooJpaActiveRecord;

@RooJavaBean
@RooToString
@RooJpaActiveRecord
public class Address {
    private String name;
}
0 голосов
/ 27 апреля 2014

Долгое время после вопроса, но у меня есть рабочее решение при попытке запустить модульные тесты Spring Roo из Eclipse ...

  1. Открыть проект в Eclipse
  2. ВEclipse, Project> Clean> Rebuild (не имеет значения, автоматический или ручной)
  3. После завершения перестройки в окне консоли выполните очистку Maven и переупаковку (требуется очистка):

    mvn clean package

или если ваши модульные тесты не пройдены в maven (и вам нужен Eclipse для отладки ваших тестов)

  mvn clean package -Dmaven.test.skip=true

4.Когда пакет будет успешным, обновите его в Eclipse.

Теперь вы сможете успешно запустить модульные тесты обратно в Eclipse.Я обнаружил, что редактирование сущностей вызывало наибольшую частоту ошибок менеджера сущностей.Когда я не мог их редактировать, я мог редактировать другие классы, и модульные тесты продолжали бы успешно выполняться.

0 голосов
/ 08 мая 2011

Я тоже столкнулся с тем же исключением, и все было настроено правильно.Я удалил проект и снова импортировал его в STS (SpringSource Tool Suite), и эта проблема исчезла.

Не знаю, почему это исправлено, но эта проблема могла быть вызвана использованием Eclipse для управления проектом, сгенерированным Roo, перед переключением на STS в моем случае.

...