【问题标题】:Spring testing and mavenSpring测试和maven
【发布时间】:2014-11-21 05:56:15
【问题描述】:

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

我在我的 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 说“无法自动装配。找不到 'UserService' 类型的 bean。 添加 @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 进行测试? (如命令'mvn clean install tomcat7:run-war-only')

【问题讨论】:

  • 不,你不需要在 tomcat 上运行这个测试,你必须告诉它要加载哪个配置文件/类。

标签: java spring maven intellij-idea junit


【解决方案1】:

您必须在测试开始之前提供要初始化的 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);
    }
}

your-spring-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>

【讨论】:

  • 我的 spring 上下文在 WEB-INF 文件夹中,我可以从这里访问它吗?
  • spring 上下文应该在 src/main/resources 或 src/test/resources .. 但你可以see here web-inf 文件夹的解决方案
  • 你也可以做@ContextConfiguration(classes = ...)风格的FWIW:stackoverflow.com/a/42138468/32453
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    根据您尝试通过测试实现的目标,您需要编写单元测试或 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 的结果执行一些自定义逻辑,则使用模拟的 UserDaoUserService 创建单元测试将是一个不错的选择。

    如果您使用构造函数注入将 dao 提供给服务,那么构建服务是轻而易举的事。如果您通过@Autowired 使用字段注入(如果可以避免,则不应该这样做),那么您需要通过反射注入模拟。一个超级实用程序是 Spring 的 ReflectionTestUtils

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


    最后请注意,上面的 cmets 与您运行测试的方式(IDE 或 Maven)无关。如果配置正确,工具会很高兴地运行它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-23
      • 2020-02-06
      • 2019-03-07
      • 1970-01-01
      • 2016-01-21
      • 1970-01-01
      • 1970-01-01
      • 2015-10-19
      相关资源
      最近更新 更多