Java 如何在SpringRoo中使用JUnit测试?(EntityManager的问题)
我正在尝试为SpringRoo项目编写JUnit测试。如果我的测试需要使用实体类,我会得到以下异常:Java 如何在SpringRoo中使用JUnit测试?(EntityManager的问题),java,junit,spring-roo,entitymanager,Java,Junit,Spring Roo,Entitymanager,我正在尝试为SpringRoo项目编写JUnit测试。如果我的测试需要使用实体类,我会得到以下异常: java.lang.IllegalStateException: Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?) SpringAspectsJAR看起来配置正确。特别是,我在pom.xml文件中有以下内容: <depen
java.lang.IllegalStateException: Entity manager has not been injected
(is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)
SpringAspectsJAR看起来配置正确。特别是,我在pom.xml
文件中有以下内容:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
org.springframework
春季方面
${spring.version}
及
真的
org.springframework
春季方面
1.6
1.6
当不是从JUnit测试调用时,使用实体类的类工作正常。知道我如何设置实体管理器以便从JUnit测试中注入吗
这是我的测试课(或多或少):
公共类服务ExampleTest{
@试验
公共void testFoo(){
FooService fs=新的FooServiceImpl();
Set foos=fs.getFoos();
}
}
这足以引发异常。FooServiceImpl类返回一组Foo,其中Foo是一个实体类。当应用程序以常规方式运行时,
getFoos()
方法起作用。这个问题只出现在单元测试的环境中。这是SpringRoo的一个令人非常恼火的问题,我还没有找到正式的解决方案
但是。。。以下是两种解决方法:
- 将SpringAspectsJAR复制到项目中,然后将其添加到项目AspectJ方面路径中
- 使用Maven运行单元测试(并错过绿色条:()
对于选项一,右键单击您的项目,选择属性->AspectJ构建->方面路径选项卡。ponzao是正确的。通过让我的测试类扩展AbstractJunit4SpringContextTests,我可以拥有所有的spring注入魔法 e、 g
您的单元测试类应该有@MockStaticEntityMethods注释。我也遇到了相同的异常,并且所有配置都正确。我删除了项目,并在STS(SpringSource工具套件)中重新导入了它,这个问题就消失了 我不确定为什么会这样做,但这个问题可能是因为在我的例子中,在切换到STS之前使用Eclipse管理Roo生成的项目造成的
单元测试类应该有@MockStaticEntityMethods注释 我只是想通过@migue为上面的答案添加更多细节,因为我花了一段时间才弄明白如何让它发挥作用。该网站确实帮助我得出了下面的答案 下面是我通过测试类注入实体管理器所做的工作。首先用@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();
}
@测试
公共void testFoo(){
//调用被测试方法调用的静态方法,以便
//“记录”它,然后在测试期间重播时设置预期响应
Foo.entityManager();
MockEntityManager expectedEntityManager=新建MockEntityManager(){
//TODO覆盖返回测试所需对象所需的方法
};
AnnotationDriveInstantityLockingControl.expectReturn(expectedEntityManager);
FooService fs=新的FooServiceImpl();
Set foos=fs.getFoos();
}
这意味着当您调用fs.getFoos()时,AnnotationDrivenStaticEntityLockingControl将注入您的模拟实体管理器,因为Foo.entityManager()是一个静态方法
还请注意,如果fs.getFoos()调用实体类(如Foo和Bar)上的其他静态方法,则它们也必须指定为此测试用例的一部分
例如,假设Foo有一个名为“getAllBars(Long fooId)”的静态查找方法,该方法在调用fs.getFoos()时被调用,那么您需要执行以下操作才能使AnnotationDriveStaticEntityLockingControl工作
@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();
}
@测试
公共void testFoo(){
//调用被测试方法调用的静态方法,以便
//“记录”它,然后在测试期间重播时设置预期响应
Foo.entityManager();
MockEntityManager expectedEntityManager=新建MockEntityManager(){
//TODO覆盖返回测试所需对象所需的方法
};
AnnotationDriveInstantityLockingControl.expectReturn(expectedEntityManager);
//调用被测试方法调用的静态方法,以便
//“记录”它,然后在测试期间重播时设置预期响应
长食物=1L;
Foo.findallbar(fooId);
List expectedBars=new ArrayList();
预期条形图。添加(新条形图(1));
预期条形图。添加(新条形图(2));
AnnotationDrivenStaticEntityLockingControl.expectReturn(expectedBars);
FooService fs=新的FooServiceImpl();
Set foos=fs.getFoos();
}
请记住,AnnotationDrivenStaticEntityLockingControl的顺序必须与fs.getFoos()调用其静态方法的顺序相同。这个问题已经问了很久了,但我在尝试从Eclipse中运行Spring Roo单元测试时有了一个可行的解决方案
mvn清洁包装
您现在应该能够在Eclipse中成功运行单元测试。我发现编辑实体导致实体管理器错误的频率最高。当我不编辑它们时,我可以编辑其他类,单元测试将继续成功运行。这对我使用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;
}
你能把你的测试课也发出来吗
@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();
}
mvn clean package -Dmaven.test.skip=true
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;
}