弹簧测试和maven

时间:2014-09-26 09:04:31

标签: java spring maven intellij-idea junit

我正在尝试测试我的Spring网络应用,但我遇到了一些问题。

我在maven中添加了一个测试类

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void testName() throws Exception {
        List<UserEntity> userEntities = userService.getAllUsers();

        Assert.assertNotNull(userEntities);
    }
}

但是当我尝试运行此测试时,我在userService上获得了NullPointerException。 IntelliJ说&#34;无法自动装配。没有'UserService&#39;的豆子找到的类型。 添加@RunWith(SpringJUnit4ClassRunner.class)后,我收到了此异常

java.lang.IllegalStateException: Neither GenericXmlContextLoader nor AnnotationConfigContextLoader was able to detect defaults, and no ApplicationContextInitializers were declared for context configuration

我该如何解决?我想我需要在我的tomcat服务器上运行这个测试,但我如何使用IntelliJ进行测试? (比如命令&m; mvn clean install tomcat7:run-war-only&#39;)

3 个答案:

答案 0 :(得分:5)

您必须在测试开始之前提供要初始化的Spring上下文文件的位置。

测试类

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration(locations = { "classpath:META-INF/your-spring-context.xml" })
public class UserServiceTest extends AbstractJUnit4SpringContextTests {

    @Autowired
    private UserService userService;

    @Test
    public void testName() throws Exception {
        List<UserEntity> userEntities = userService.getAllUsers();

        Assert.assertNotNull(userEntities);
    }
}

您 - 弹簧 - context.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="userService" class="java.package.UserServiceImpl"/>

</beans>

答案 1 :(得分:4)

根据您尝试通过测试实现的目标,您需要编写单元测试或Spring集成测试。

在后一种情况下,您需要将代码更改为:

@ContextConfiguration(locations = {"classpath:/applicationContext.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class UserServiceTest {

   @Autowired
   private UserService userService;

    //test whatever
}

执行此类集成测试时,您可能希望挂钩Spring Profile机制。通过利用它,您将能够重复使用您在生产代码中使用的相同配置,同时有选择地替换某些bean(例如,通过将生产数据源与内存数据库交换)。

如果您使用的是Spring 4,那么Conditional会为您提供更大的灵活性。

我建议您对Spring测试文档中的this部分进行一次很好的阅读,以便大致了解Spring集成测试可以为您做些什么。


您提交的案例我不确定是否需要进行集成测试(有关UserService实际执行的更多详细信息会给出更清晰的图片。)

例如,如果UserService使用UserDao,然后对dao的结果执行一些自定义逻辑,则使用模拟的UserServiceUserDao创建单元测试是一个不错的选择。

如果您使用构造函数注入来为服务提供dao,那么构建服务是明智的。如果您通过@Autowired使用现场注入(如果可以避免,则不应该使用),那么您需要通过反射注入模拟。一个超级实用工具是Spring的ReflectionTestUtils

然后你可以为UserDao创建一个集成测试,测试它是否能正确读取数据库中的数据。


最后请注意,上面的注释与运行测试的方式(IDE或Maven)无关。如果配置正确,工具将很乐意运行它

答案 2 :(得分:2)

我不确定,但认为您需要将 locations 属性添加到ContextConfiguration批注中,您可以在其中指定所有bean存在的xml文件。此外,我想获取所有用户的操作与数据库相关,因此最好添加TransactionConfiguration注释。因此,你应该有这样的事情:

  

@ContextConfiguration(locations = {&#34; classpath:spring-config-junit.xml&#34;})   @TransactionConfiguration(transactionManager =&#34; transactionManager&#34;,defaultRollback = true)