2010-07-19 5 views
6

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

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

весной аспекты JAR выглядит быть настроен правильно. В частности, у меня есть следующие в файле 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. Любая идея, как я могу настроить вещи так, чтобы менеджер Entity был введен из теста JUnit?

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

public class ServiceExampleTest { 

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

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

+0

Не могли бы вы опубликовать свой тестовый класс, а? Я никогда не использовал Spring Roo, но при обычных тестах Spring вы обычно должны расширять AbstractSpringJUnit4Test (или что-то еще) или использовать пользовательский Spring runner с помощью аннотации для тестов. – ponzao

ответ

3

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

... Но вот два пути:

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

для вариант одной правой кнопкой мыши на вашем проекте выберите свойства-> AspectJ Build -.> Aspect Path Tab

+0

Я приму этот ответ, но я не могу его легко проверить, поскольку я больше не использую Roo. (Я на другой работе.) –

+0

@FarmBoy Вы не можете сказать, что, не сказав, что вы используете сейчас :) –

+0

Groovy/Grails. Я люблю это. –

6

ponzao правильно, я могу. у вас есть все магия впрыскивания весны, когда мой тестовый класс расширяет AbstractJunit4SpringContextTests.

например.

@ContextConfiguration(locations = { "/META-INF/spring/applicationContext.xml" }) 
public class SelfRegistrationTest extends AbstractJUnit4SpringContextTests { 
+0

Кажется, противно, но, похоже, работает на меня. – kipz

1

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

0

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

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

3

Ваш класс тестирования единицы должен иметь аннотацию @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() вызывает его статические методы.

0

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

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

    mvn clean package

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

mvn clean package -Dmaven.test.skip=true 

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

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

0

Это работает для меня с 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'); 
     } 
    } 
} 

С Адрес класса, как это:

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; 
} 
Смежные вопросы