【问题标题】:Exception when building the ApplicationContext for a JUnit test in Activiti with Spring Boot使用 Spring Boot 在 Activiti 中为 JUnit 测试构建 ApplicationContext 时出现异常
【发布时间】:2015-07-18 12:31:55
【问题描述】:

每当我尝试使用 Spring Boot 为 Activiti 运行以下 JUnit 测试时,我都无法解决以下异常。

例外:

2015-05-07 20:15:00 org.springframework.test.context.TestContext.<init>(93@main) INFO @ContextConfiguration not found for class [class ProcessXTest].
2015-05-07 20:15:00 org.springframework.test.context.TestContextManager.retrieveTestExecutionListeners(143@main) INFO @TestExecutionListeners is not present for class [class ProcessXTest]: using defaults.
2015-05-07 20:15:00 org.springframework.test.context.TestContextManager.prepareTestInstance(234@main) ERROR Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@232023ff] to prepare test instance [ProcessXTest@131b4c5d]
java.lang.IllegalArgumentException: Can not build an ApplicationContext with a NULL 'contextLoader'. Consider annotating your test class with @ContextConfiguration.

JUnit 测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { Application.class })
public class ProcessXTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProcessXTest.class);

    private static final String BPMN_LOCATION = "./src/main/resources/processes/processx.bpmn";
    private static final String BPMN_NAME = "processx.bpmn";
    private static final String PROCESS_KEY = "processx";

    @Rule
    public ActivitiRule activitiRule = new ActivitiRule();

    @Before
    public void loadProces() throws FileNotFoundException {
        LOGGER.debug("Loading the model for unit testing.");

        RepositoryService repositoryService = activitiRule.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment().addInputStream(BPMN_NAME, new FileInputStream(BPMN_LOCATION)).deploy();
        assertNotNull(deployment.getId());

        assertTrue(repositoryService.getDeploymentResourceNames(deployment.getId()).contains(bpmnName));
    }

    @Test
    public void testProces() {
        LOGGER.debug("Unit testing the process.");

        TaskService taskService = activitiRule.getTaskService();
        List<Task> tasks = taskService.createTaskQuery().list();
        assertEquals(tasks.size(), 0);

        ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey(PROCESS_KEY, new HashMap<String, Object>()); 
        assertNotNull(processInstance.getId());

        tasks = taskService.createTaskQuery().list();
        assertEquals(tasks.size(), 1);
    }
}

主应用程序类(所有 bean 都在该类中定义,因此不使用外部 XML 上下文配置文件):

@SpringBootApplication
@EnableConfigurationProperties
public class Application {

    public static void main(final String[] args) {
       SpringApplication.run(Application.class, args);
    }

    @Bean
    public CommandLineRunner init() {
        return new CommandLineRunner() {
            @Override
            public void run(final String... strings) throws Exception {
                // initialization on start-up
            }
        };
    }

    ...more beans
}

我正在使用以下依赖项:

compile 'org.activiti:activiti-engine:5.17.0'
compile 'org.activiti:spring-boot-starter-basic:5.17.0'
compile 'org.activiti:spring-boot-starter-rest-api:5.17.0'

compile 'junit:junit:4.12'

compile 'org.springframework.boot:spring-boot-starter-web:1.2.3.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-test:1.2.3.RELEASE'

【问题讨论】:

  • 您是否尝试使用 @ContextConfiguration 注释您的测试类?
  • 添加此注解会返回以下异常:2015-05-07 22:41:57 org.springframework.test.context.TestContextManager.prepareTestInstance(234@main) ERROR Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@367cca66] to prepare test instance [ProcessXTest@3acc0a7c] exception is java.io.FileNotFoundException: class path resource [ProcessXTest-context.xml] cannot be opened because it does not exist
  • 那么你在它试图找到它的地方有一个 contextconfiguration xml 吗?看看例如stackoverflow.com/questions/4377699/…spring.io/blog/2011/06/21/…。看来你也可以试试@Configuration注解。
  • 是的,我能够通过引入 XML 上下文配置文件(没有定义 bean)来绕过异常。但是,这在运行测试时会在 repositoryService.createDeployment() 上提供一个空指针。我不喜欢使用任何外部 XML 上下文配置文件,因为所有的 bean 都已经在主应用程序类中定义了。

标签: java exception junit spring-boot activiti


【解决方案1】:

我的解决方案:

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.spring.boot.AbstractProcessEngineConfiguration;
import org.junit.Rule;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(AbstractSpringTest.ActivitiEngineTestConfiguration.class)
@ActiveProfiles("test")
public abstract class AbstractSpringTest {

    @Autowired @Rule
    public ActivitiRule activitiRule;

    @SpringBootApplication
    public static class ActivitiEngineTestConfiguration {

        @Bean
        public ActivitiRule activitiRule(ProcessEngine processEngine) {
            return new ActivitiRule(processEngine);
        }
    }
}

有一个文件 application-test.properties 包含(在本例中使用 h2):

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:activiti?characterEncoding=UTF-8
spring.datasource.username=sa
spring.datasource.password=sa

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true

AbstractSpringTest 的每个子类都可以使用例如@Deployment:

public class ConcreteTest extends AbstractSpringTest {

    @Test
    @Deployment(resources = {"processes/test_process.bpmn20.xml"})
    public void testSomething() {
    }
}

【讨论】:

    【解决方案2】:

    我最终通过如下定义 JUnit 测试解决了这个问题:

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = { Application.class })
    public class ProcessXTest {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(ProcessXTest.class);
    
        private static final String BPMN_LOCATION = "./src/main/resources/processes/processx.bpmn";
        private static final String BPMN_NAME = "processx.bpmn";
        private static final String PROCESS_KEY = "processx";
    
        @Autowired
        private RepositoryService repositoryService;
    
        @Autowired
        private RuntimeService runtimeService;
    
        @Autowired
        private TaskService taskService;
    
        @Autowired
        private HistoryService historyService;
    
        @Before
        public void loadModel() throws FileNotFoundException {
            LOGGER.debug("Loading the model for unit testing.");
    
            Deployment deployment = repositoryService.createDeployment().addInputStream(BPMN_NAME, new FileInputStream(BPMN_LOCATION)).deploy();
            assertNotNull(deployment.getId());
            assertTrue(repositoryService.getDeploymentResourceNames(deployment.getId()).contains(bpmnName));
        }
    
        @Test
        public void testProcess() {
            LOGGER.debug("Unit testing the process.");
    
            List<Task> tasks = taskService.createTaskQuery().list();
            assertEquals(tasks.size(), 0);
    
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(PROCESS_KEY, new HashMap<String, Object>());
            assertNotNull(processInstance.getId());
    
            tasks = taskService.createTaskQuery().list();
            assertEquals(tasks.size(), 1);
        }
    }
    

    考虑到@ActivitiRule 默认使用类路径上的 activiti.cfg.xml 资源来初始化 ProcessEgine,我不得不修改我的 JUnit 测试:http://activiti.org/javadocs/org/activiti/engine/test/ActivitiRule.html

    【讨论】:

      猜你喜欢
      • 2019-03-11
      • 2018-11-09
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      • 2019-01-30
      • 2018-08-27
      • 2021-10-13
      • 1970-01-01
      相关资源
      最近更新 更多