OK, may be I need to read some more information abotu usage templates, tests and so on under Spring... but I found another problem trying to test my processes with jbpm31 spring module.
So, here is basic class for testing processes:
Code:
package ru.emdev.EmDevProcesses.tests;
import ...;
/*AbstractTransactionalDataSourceSpringContextTests*/
/** Basic class for Process Tests
*
*/
public class AbstractProcessTest extends AbstractTransactionalDataSourceSpringContextTests {
private static Log log = LogFactory.getLog(AbstractProcessTest.class);
/// template class to store jbpm template
/// setTemplate implemented in every test case to get
/// the exactly template we are going to test
JbpmTemplate m_template;
JbpmContext m_jbpmContext;
/** Special call-back interface for performing tests
*
*/
public interface ProcessTestCallback {
public void doTest();
};
/** this function is used for performing test specified in call back class
*
* This method is required for placing whole test into Jbpm context
*
* @param i_callBack
*/
protected void executeTest(final ProcessTestCallback i_callBack) {
m_template.execute(new JbpmCallback() {
public Object doInJbpm(JbpmContext context) {
m_jbpmContext = context;
try {
i_callBack.doTest();
} finally {
m_jbpmContext = null;
}
return null;
}
});
}
protected String[] getConfigLocations() {
return new String[] {"ru/emdev/EmDevProcesses/tests/applicationContext.xml"};
}
/** Starts New Process
*
* This function starts new process for m_processDef,
* assigns description and process owner
* @param i_description - description for created process
* @param i_user - owner for created process
*
* @return Start Task Instance for created Process
*/
protected TaskInstance startProcess(String i_description,
String i_user) {
assertNotNull(m_jbpmContext);
assertNotNull(i_description);
assertNotNull(i_user);
log.info("Start new Process");
/*
ProcessInstance process = (ProcessInstance)m_template.execute(new JbpmCallback() {
public Object doInJbpm(JbpmContext context) {
context.getGraphSession().saveProcessDefinition(m_template.getProcessDefinition());
ProcessDefinition processDef = context.getGraphSession().findLatestProcessDefinition(m_template.getProcessDefinition().getName());
ProcessInstance process = processDef.createProcessInstance();
return process;
}
});
*/
m_jbpmContext.getGraphSession().saveProcessDefinition(m_template.getProcessDefinition());
ProcessDefinition processDef = m_jbpmContext.getGraphSession().findLatestProcessDefinition(m_template.getProcessDefinition().getName());
ProcessInstance process = processDef.createProcessInstance();
assertNotNull(process);
//get start task
TaskInstance startTask = process.getTaskMgmtInstance().createStartTaskInstance();
assertNotNull(startTask);
// now, assign initial values to the task
startTask.setVariable(JbpmTaskImpl.DESCRIPTION_VARIABLE, i_description);
startTask.setVariable(JbpmProcessDefImpl.OWNER_VARIABLE, i_user);
return startTask;
}
/** Ends the specified task and check next task assignment
*
* @param i_prevTask - task to end
* @param i_nextTaskOwner- owner of next assigned task
* @param i_nextTaskName - name of the next task
*
* @return next task
*/
protected TaskInstance endTask(final TaskInstance i_prevTask,
String i_nextTaskOwner,
String i_nextTaskName) {
assertNotNull(i_prevTask);
assertNotNull(i_nextTaskOwner);
assertNotNull(i_nextTaskName);
log.info("Finish Task " + i_prevTask.getName());
// end task
i_prevTask.end();
/*
m_template.execute(new JbpmCallback() {
public Object doInJbpm(JbpmContext context) {
context.save(i_prevTask);
return null;
}
});
*/
// get current task
TaskInstance task = getOneTask(i_nextTaskOwner, i_nextTaskName);
// check next node
checkNode(task.getToken(), i_nextTaskName);
return task;
}
/** Ends the specified task by specified transition
* and check next task assignment
*
* @param i_transitionName - transition to leave the node
* @param i_prevTask - task to end
* @param i_nextTaskOwner- owner of next assigned task
* @param i_nextTaskName - name of the next task
*
* @return next task
*/
protected TaskInstance endTask(TaskInstance i_prevTask,
String i_transitionName,
String i_nextTaskOwner,
String i_nextTaskName) {
assertNotNull(i_prevTask);
assertNotNull(i_transitionName);
assertNotNull(i_nextTaskOwner);
assertNotNull(i_nextTaskName);
// end task
i_prevTask.end(i_transitionName);
//m_jbpmContext.save(i_prevTask);
// check next node
checkNode(i_prevTask.getToken(), i_nextTaskName);
// get current task
TaskInstance task = getOneTask(i_nextTaskOwner, i_nextTaskName);
return task;
}
/** check the node for specified token
*
* @param i_token token to check
* @param i_nodeName - name of expected node
*/
protected void checkNode(Token i_token, String i_nodeName) {
assertNotNull(i_token);
assertNotNull(i_nodeName);
Node node = i_token.getNode();
assertNotNull(node);
assertEquals(i_nodeName, node.getName());
}
/** Checks that specified user has only one task with specified name and returns this task
*
* @param i_user - user to check
* @param i_taskName - expected task name
*
* @return expected task
*/
protected TaskInstance getOneTask(String i_user, String i_taskName) {
assertNotNull(m_jbpmContext);
assertNotNull(i_user);
assertNotNull(i_taskName);
//List tasks = m_template.findTaskInstances(i_user);
List tasks = m_jbpmContext.getTaskMgmtSession().findTaskInstances(i_user);
assertNotNull(tasks);
assertEquals(i_user + " should have only 1 task",
1,
tasks.size());
TaskInstance task = (TaskInstance)tasks.get(0);
assertNotNull(task);
//check task instance name
assertEquals(i_taskName, task.getName());
return task;
}
/** Checks that specified user has not active tasks assigned to him
*
* @param i_user - user to check
*/
protected void checkNoTasks(String i_user) {
assertNotNull(m_jbpmContext);
assertNotNull(i_user);
// user akakunin should have no tasks
//List tasks = m_template.findTaskInstances(i_user);
List tasks = m_jbpmContext.getTaskMgmtSession().findTaskInstances(i_user);
assertEquals(i_user + " should have no task",
0,
tasks.size());
}
}
What actually it did:
- Inherited from AbstractTransactionalDataSourceSpringContextTests for transactions support
- Declare special callback class for executing test code
- Declare function, that executes specified in callback code inside JbpmContext. Before execution it gets JbpmContext variable to use it in test, and after execution it set it to null
Test derived from this class looks like:
Code:
package ru.emdev.EmDevProcesses.tests;
public class ToDoProcessTestCase extends AbstractProcessTest {
public void setTodoTemplate(JbpmTemplate i_template) {
m_template = i_template;
}
public void testShortWay() {
executeTest(new ProcessTestCallback() {
public void doTest() {
//get start task
TaskInstance startTask = startProcess("Do something!", "somebody");
TaskInstance nextTask = endTask(startTask, "somebody", "Assign ToDo");
assertNotNull(nextTask);
// ...
// do something extra
// ...
}
});
}
public void testReject() {
executeTest(new ProcessTestCallback() {
public void doTest() {
//get start task
TaskInstance startTask = startProcess("Do something!", "somebody");
TaskInstance nextTask = endTask(startTask, "somebody", "Assign ToDo");
assertNotNull(nextTask);
// ...
// do something extra
// ...
}});
}
}
So, it work quite fine and solves all problem I had before:
- No problem with jbpm configuration I initially had
- Whole test code is performed in one JbpmContext, so it works
In my console I can see followed strings:
Code:
5989 [main] INFO ru.emdev.EmDevProcesses.tests.ToDoProcessTestCase - Began transaction (1): transaction manager [org.springframework.orm.hibernate3.HibernateTransactionManager@1570c24]; default rollback = true
5989 [main] INFO ru.emdev.EmDevProcesses.tests.AbstractProcessTest - Start new Process
6560 [main] INFO ru.emdev.EmDevProcesses.tests.ToDoProcessTestCase - Rolled back transaction after test execution
So, seems transactions works... but.... I have no test isolation!
Task created,assigned to somebody and not closed in one test still assigned in another 
Oh... seems all these staff should make our life easily... But I already spent too much time trying to make my working non-spring based working tests working in spring-based environment... May be I do something totally wronge?
Are somethere any workable example available?
Thank you for any advice!