JUnit testing Spring Security, Spring MVC and Activiti BPM

Spring Test MVC is a good framework for JUnit testing Spring MVC based application. In this sample, we demonstrated a simple LoanRequest application where in we test the Spring Security, Spring MVC and Activiti BPM Spring Support.

For people in hurry,

  • Get the latest Spring Test MVC code base
  • run “mvn clean install” on the above codebase
  • Get the loanrequest codebase latest code from @ Github
  • At the command prompt type “mvn test”, if the tests are successful, you are all set.

Details: JUnit testing Spring Security, Spring MVC and Activiti BPM

Spring Test MVC is an awesome framework to test the Spring MVC backend code. Spring Test MVC framework has a built in Spring MVC web container. You can point it to the webapp folder, and the spring application context and it will configure the buildin container to work with the JUnit test. You can also configure the Spring Security as below,

//You need to define a class as below,
class WebContextLoader extends GenericWebContextLoader {
public WebContextLoader() {
super("src/main/webapp", false);
}
}

//In your test case you need to configure the WebContexLoader as below with the Spring context files
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = WebContextLoader.class, value = {
"classpath:META-INF/spring/applicationContext-activiti.xml",
"classpath:META-INF/spring/applicationContext-security.xml",
"classpath:META-INF/spring/applicationContext.xml",
"classpath:META-INF/spring/test-datasource-config.xml"})
public class LoanRequestControllerTest {

//this FilterChainProxy configures the Spring Security feature
@Autowired
private FilterChainProxy springSecurityFilterChain;

@Autowired
private WebApplicationContext wac;

private MockMvc mockMvc;

@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webApplicationContextSetup(this.wac)
.addFilters(this.springSecurityFilterChain).build();
}

The API syntax is simple and expresses technical functionality closely, for example if the LoanRequest usecase is as below,

  • The accountant logged in and submitted the LoanRequest. The Server will return the HTTP Status as ok, and you can also assert if the Submitting went thru
  • Once the Accountant submitted the LoanRequest, the Management can review it and approve the Loan request

The above flow can be expressed by the below code using the TDD methodology,


@Test
public void testApprove() throws Exception {
mockMvc.perform(
post("/loanrequests/create").param("id", "4")
.param("customerName", "krishna").param("amount", "26")
.with(userDeatilsService("fozzie")))
.andExpect(status().isOk()).andExpect(redirectedUrl("/list"))
.andExpect(model().attribute("loanRequests", any(List.class)));

mockMvc.perform(
get("/loanrequestsapproval/approve/4").with(userDeatilsService("kermit")))
.andExpect(status().isOk());
}

If you notice, the http actions like Post and Get are demonstrated here. Also it has demonstrated how the user logging happens.

This container is configured to work with Spring Security, for example, if an accountant logs into to approval page, it will be forbidden. We write the test using TDD as below,


@Test
public void testApproveForbidden() throws Exception {
mockMvc.perform(
get("/loanrequestsapproval/approve/2").with(userDeatilsService("fozzie")))
.andExpect(status().isForbidden());
}

This sample also demonstrates the capability of Activiti BPM and how it can participate in JUnit testing.

You can configure the inmemory Activity Process Engine Configuration along with the deployed Bpmns as below,

<!-- <bean id="processEngineConfiguration"> -->
<bean id="processEngineConfiguration">
<property name="dataSource" ref="dataSource-activiti" />
<property name="databaseSchemaUpdate" value="true" />
<property name="transactionManager" ref="transactionManager" />
<property name="jpaHandleTransaction" value="false" />
<property name="jpaCloseEntityManager" value="false" />
<property name="jobExecutorActivate" value="false" />
<property name="deploymentResources" value="classpath*:/org/activiti/spring/test/usertask/LoanProcess.bpmn20.xml" />
</bean>

In the JUnit test TDD you can autowire this as below and populate some sample users,


@Autowired
SpringProcessEngineConfiguration processEngineConfiguration;

@Before
public void setup() {
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();

IdentityService identityService = processEngine.getIdentityService();
User user = identityService.newUser("fozzie");
user.setPassword("fozzie");
identityService.saveUser(user);
user = identityService.newUser("kermit");
user.setPassword("kermit");
identityService.saveUser(user);

identityService.saveGroup(identityService.newGroup("accountancy"));
identityService.saveGroup(identityService.newGroup("management"));

identityService.createMembership("fozzie", "accountancy");
identityService.createMembership("kermit", "management");
}

In your controller, you can autowire the inmemory Activity Process Engine Configuration and start a process, approve a task and mark it as complete. For more details refer the LoanRequestController code.

Conclusion

In this example, I have demonstrated a Activiti BPM based workflow initiated from a Spring MVC container and goes thru a lifecycle. I also demonstrated how Spring Security is used to authorize the Activiti BPM users.

I hope this example helps.

Advertisements

4 thoughts on “JUnit testing Spring Security, Spring MVC and Activiti BPM

  1. Pingback: spring-test-mvc junit testing Spring Security layer with InMemoryDaoImpl | Krishna's Blog

  2. pension Plan rules

    Just wish to say your article is as surprising. The clarity in your post is just cool
    and i can assume you’re an expert on this subject. Fine with your permission allow me to grab your feed to keep updated with forthcoming post. Thanks a million and please continue the rewarding work.

    Reply
  3. Pingback: fstyle.de » Spring-Test & Spring Security: How to mock Authentication

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s