AnsweredAssumed Answered

Using PersonTest.java JUnit test for testing a custom behavior.

Question asked by kooroshv on Feb 21, 2013
Latest reply on Feb 28, 2013 by mrogers
I have made some progress with this issue.

Let's recap.

I am trying to unit test a custom behavior which is triggered on Person node creation. I am using the Alfresco Junit test as guide:


org.alfresco.repo.security.person.PersonTest

I have placed it under my Alfresco project. Here is the modified code:


/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package com.companyx.module;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import javax.transaction.Status;
import javax.transaction.UserTransaction;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.security.person.PersonException;
import org.alfresco.repo.security.person.UserNameMatcherImpl;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.NoSuchPersonException;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.security.PersonService.PersonInfo;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.tools.RenameUser;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.BaseApplicationContextHelper;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.GUID;
import org.alfresco.util.Pair;
import org.alfresco.util.PropertyMap;
import org.springframework.context.ApplicationContext;

public class PersonTest extends TestCase
{
    private static ApplicationContext ctx = MyApplicationContextHelper.getApplicationContext();
   
    private TransactionService transactionService;
    private PersonService personService;
    private UserNameMatcherImpl userNameMatcher;

    private BehaviourFilter policyBehaviourFilter;
    private NodeService nodeService;
    private NodeRef rootNodeRef;
    private PermissionService permissionService;
    private AuthorityService authorityService;
    private MutableAuthenticationDao authenticationDAO;
    private UserTransaction testTX;

    @SuppressWarnings("deprecation")
    public void setUp() throws Exception
    {
        AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());
       
        if (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_NONE)
        {
            throw new AlfrescoRuntimeException(
                    "A previous tests did not clean up transaction: " +
                    AlfrescoTransactionSupport.getTransactionId());
        }
       
        transactionService = (TransactionService) ctx.getBean("TransactionService");
        personService = (PersonService) ctx.getBean("PersonService");
        userNameMatcher = (UserNameMatcherImpl) ctx.getBean("userNameMatcher");
        nodeService = (NodeService) ctx.getBean("nodeService");
        permissionService = (PermissionService) ctx.getBean("permissionService");
        authorityService = (AuthorityService) ctx.getBean("authorityService");
        authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
        policyBehaviourFilter = (BehaviourFilter) ctx.getBean("policyBehaviourFilter");
       
        testTX = transactionService.getUserTransaction();
        testTX.begin();
       
        StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
        rootNodeRef = nodeService.getRootNode(storeRef);
       
        for (NodeRef nodeRef : personService.getAllPeople())
        {
            String uid = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME));
            if (!uid.equals(AuthenticationUtil.getAdminUserName()) && !uid.equals(AuthenticationUtil.getGuestUserName()))
            {
                personService.deletePerson(nodeRef);
            }
        }
       
        personService.setCreateMissingPeople(true);
       
        testTX.commit();
        testTX = transactionService.getUserTransaction();
        testTX.begin();
    }

    @Override
    protected void tearDown() throws Exception
    {
        userNameMatcher.setUserNamesAreCaseSensitive(false); // Put back the default

        if ((testTX.getStatus() == Status.STATUS_ACTIVE) || (testTX.getStatus() == Status.STATUS_MARKED_ROLLBACK))
        {
            testTX.rollback();
        }
        AuthenticationUtil.clearCurrentSecurityContext();
        super.tearDown();
    }

    public void testPersonCRUD()
    {
        personService.setCreateMissingPeople(false);
        personService.createPerson(createDefaultProperties("Derek", "Derek", "Hulley", "dh@dh", "alfresco", rootNodeRef));
        testProperties(personService.getPerson("Derek"), "Derek", "Derek", "Hulley", "dh@dh", "alfresco");

        personService.deletePerson("Derek");
        assertEquals(1, getPeopleCount());

    }
   
    private Map<QName, Serializable> createDefaultProperties(String userName, String firstName, String lastName, String email, String orgId, NodeRef home)
    {
        HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>();
        properties.put(ContentModel.PROP_USERNAME, userName);
        properties.put(ContentModel.PROP_HOMEFOLDER, home);
        properties.put(ContentModel.PROP_FIRSTNAME, firstName);
        properties.put(ContentModel.PROP_LASTNAME, lastName);
        properties.put(ContentModel.PROP_EMAIL, email);
        properties.put(ContentModel.PROP_ORGID, orgId);
        return properties;
    }

    private int getPeopleCount()
    {
        // Can either get a large page with all results (up to a given max) …
       
        PagingRequest pagingRequest = new PagingRequest(20000, null); // note: people (up to max of 20000)
        int count = personService.getPeople(null, true, null, pagingRequest).getPage().size();
       
        // … or request 1 item + total count (up to a given max)
       
        pagingRequest = new PagingRequest(0, 1, null);
        pagingRequest.setRequestTotalCountMax(20000); // note: request total people count (up to max of 20000)
       
        PagingResults<PersonInfo> ppr = personService.getPeople(null, true, null, pagingRequest);
       
        Pair<Integer, Integer> totalResultCount = ppr.getTotalResultCount();
        assertNotNull(totalResultCount);
        assertTrue(totalResultCount.getFirst() == totalResultCount.getSecond());
       
        assertEquals(count, totalResultCount.getFirst().intValue());
       
        return count;
       
    }

    private void testProperties(NodeRef nodeRef, String userName, String firstName, String lastName, String email, String orgId)
    {
        assertEquals(userName, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME)));
        assertNotNull(nodeService.getProperty(nodeRef, ContentModel.PROP_HOMEFOLDER));
        assertEquals(firstName, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_FIRSTNAME)));
        assertEquals(lastName, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_LASTNAME)));
        assertEquals(email, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_EMAIL)));
        assertEquals(orgId, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_ORGID)));
    }

    private void checkPeopleContain(String userName)
    {
        PagingRequest pagingRequest = new PagingRequest(0, 20000, null);
        PagingResults<PersonInfo> ppr = personService.getPeople(null, true, null, pagingRequest);
       
        boolean found = false;
        for (PersonInfo person : ppr.getPage())
        {
            if (person.getUserName().equals(userName))
            {
                found = true;
                break;
            }
        }
        assertTrue(found);
    }
   
    static class MyApplicationContextHelper extends BaseApplicationContextHelper
    {  
        /** location of required configuration files */
        final static String[] CONFIG_LOCATIONS = new String[] { "classpath:test-database-context.xml",
              "classpath:nodeService/test-component-context.xml"};
//           "classpath:alfresco/application-context.xml" };
       
        /**
         * Provides a static, single instance of the default Alfresco application context.  This method can be
         * called repeatedly.
         * <p/>
         * If the configuration requested differs from one used previously, then the previously-created
         * context is shut down.
         *
         * @return Returns an application context for the default Alfresco configuration
         */
        static synchronized ApplicationContext getApplicationContext()
        {
            return BaseApplicationContextHelper.getApplicationContext(CONFIG_LOCATIONS);
        }
    }
}




Before I was using "application-context.xml" to get Alfresco context. It resulted in Junit test failing with following stack trace:

<blockcode>
java.lang.ExceptionInInitializerError
   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
   at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
   at junit.framework.TestSuite.createTest(TestSuite.java:61)
   at junit.framework.TestSuite.addTestMethod(TestSuite.java:294)
   at junit.framework.TestSuite.addTestsFromTestCase(TestSuite.java:150)
   at junit.framework.TestSuite.<init>(TestSuite.java:129)
   at org.junit.internal.runners.JUnit38ClassRunner.<init>(JUnit38ClassRunner.java:71)
   at org.junit.internal.builders.JUnit3Builder.runnerForClass(JUnit3Builder.java:14)
   at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
   at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
   at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
   at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tenantService' defined in file [C:\Users\koo\Alfresco-Project\code\alfresco\sdk\lib\server\config\alfresco\mt\mt-context.xml]: Cannot resolve reference to bean 'tenantAdminDAO' while setting bean property 'tenantAdminDAO'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tenantAdminDAO' defined in class path resource [alfresco/dao/dao-context.xml]: Cannot resolve reference to bean 'repoSqlSessionTemplate' while setting bean property 'sqlSessionTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'repoSqlSessionTemplate' defined in class path resource [alfresco/ibatis/ibatis-context.xml]: Cannot resolve reference to bean 'repoSqlSessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'repoSqlSessionFactory' defined in class path resource [alfresco/ibatis/ibatis-context.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [alfresco/ibatis/alfresco-SqlMapConfig.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Failed to get resource: alfresco/ibatis/#resource.dialect#/audit-insert-SqlMap.xml
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
   at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
   at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
   at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
   at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
   at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
   at org.alfresco.util.BaseApplicationContextHelper.getApplicationContext(BaseApplicationContextHelper.java:67)
   at org.alfresco.util.ApplicationContextHelper.getApplicationContext(ApplicationContextHelper.java:46)
   at com.companyx.module.PersonTest.<clinit>(PersonTest.java:74)
   … 22 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tenantAdminDAO' defined in class path resource [alfresco/dao/dao-context.xml]: Cannot resolve reference to bean 'repoSqlSessionTemplate' while setting bean property 'sqlSessionTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'repoSqlSessionTemplate' defined in class path resource [alfresco/ibatis/ibatis-context.xml]: Cannot resolve reference to bean 'repoSqlSessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'repoSqlSessionFactory' defined in class path resource [alfresco/ibatis/ibatis-context.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [alfresco/ibatis/alfresco-SqlMapConfig.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Failed to get resource: alfresco/ibatis/#resource.dialect#/audit-insert-SqlMap.xml
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
   at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
   … 39 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'repoSqlSessionTemplate' defined in class path resource [alfresco/ibatis/ibatis-context.xml]: Cannot resolve reference to bean 'repoSqlSessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'repoSqlSessionFactory' defined in class path resource [alfresco/ibatis/ibatis-context.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [alfresco/ibatis/alfresco-SqlMapConfig.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Failed to get resource: alfresco/ibatis/#resource.dialect#/audit-insert-SqlMap.xml
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
   at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:616)
   at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:148)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
   at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
   … 49 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'repoSqlSessionFactory' defined in class path resource [alfresco/ibatis/ibatis-context.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [alfresco/ibatis/alfresco-SqlMapConfig.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Failed to get resource: alfresco/ibatis/#resource.dialect#/audit-insert-SqlMap.xml
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
   at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
   … 61 more
Caused by: org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [alfresco/ibatis/alfresco-SqlMapConfig.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Failed to get resource: alfresco/ibatis/#resource.dialect#/audit-insert-SqlMap.xml
   at org.alfresco.ibatis.HierarchicalSqlSessionFactoryBean.buildSqlSessionFactory(HierarchicalSqlSessionFactoryBean.java:248)
   at org.alfresco.ibatis.HierarchicalSqlSessionFactoryBean.afterPropertiesSet(HierarchicalSqlSessionFactoryBean.java:98)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
   … 68 more
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Failed to get resource: alfresco/ibatis/#resource.dialect#/audit-insert-SqlMap.xml
   at org.alfresco.ibatis.HierarchicalXMLConfigBuilder.parseConfiguration(HierarchicalXMLConfigBuilder.java:128)
   at org.alfresco.ibatis.HierarchicalXMLConfigBuilder.parse(HierarchicalXMLConfigBuilder.java:110)
   at org.alfresco.ibatis.HierarchicalSqlSessionFactoryBean.buildSqlSessionFactory(HierarchicalSqlSessionFactoryBean.java:246)
   … 71 more
Caused by: org.apache.ibatis.builder.BuilderException: Failed to get resource: alfresco/ibatis/#resource.dialect#/audit-insert-SqlMap.xml
   at org.alfresco.ibatis.HierarchicalXMLConfigBuilder.mapperElement(HierarchicalXMLConfigBuilder.java:306)
   at org.alfresco.ibatis.HierarchicalXMLConfigBuilder.parseConfiguration(HierarchicalXMLConfigBuilder.java:124)
   … 73 more

</blockcode>

Now with the custom context files:

"classpath:test-database-context.xml", "classpath:nodeService/test-component-context.xml"

I am using H2 for database and getting past the original errors. Now my error is:

<blockcode>
java.lang.ExceptionInInitializerError
   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
   at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
   at junit.framework.TestSuite.createTest(TestSuite.java:61)
   at junit.framework.TestSuite.addTestMethod(TestSuite.java:294)
   at junit.framework.TestSuite.addTestsFromTestCase(TestSuite.java:150)
   at junit.framework.TestSuite.<init>(TestSuite.java:129)
   at org.junit.internal.runners.JUnit38ClassRunner.<init>(JUnit38ClassRunner.java:71)
   at org.junit.internal.builders.JUnit3Builder.runnerForClass(JUnit3Builder.java:14)
   at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
   at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
   at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
   at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 112 in XML document from class path resource [nodeService/test-component-context.xml] is invalid; nested exception is org.xml.sax.SAXParseException: An element with the identifier "exceptionTranslator" must appear in the document.
   at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)
   at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
   at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
   at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
   at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
   at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
   at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
   at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:126)
   at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:92)
   at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
   at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)
   at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)
   at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
   at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
   at org.alfresco.util.BaseApplicationContextHelper.getApplicationContext(BaseApplicationContextHelper.java:67)
   at com.synopsys.submitit.module.PersonTest$MyApplicationContextHelper.getApplicationContext(PersonTest.java:236)
   at com.synopsys.submitit.module.PersonTest.<clinit>(PersonTest.java:74)
   … 22 more
Caused by: org.xml.sax.SAXParseException: An element with the identifier "exceptionTranslator" must appear in the document.
   at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
   at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)
   at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
   at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
   at org.apache.xerces.impl.dtd.XMLDTDValidator.handleEndElement(Unknown Source)
   at org.apache.xerces.impl.dtd.XMLDTDValidator.endElement(Unknown Source)
   at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
   at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
   at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
   at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
   at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
   at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
   at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
   at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
   at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
   at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
   … 38 more

</blockcode>

The context files are:

test-database-context.xml
=========================
<blockcode>
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>

   <!– import resource="classpath:*/test-resources/dev-context.xml" /–>
   <bean
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

      <property name="locations">
        <list>
         <value>alfresco-global.properties</value>
         <value>extra-test.properties</value>
        </list>
      </property>
   </bean>

   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close">
      <property name="driverClassName">
         <value>${db.driver}</value>
      </property>
      <property name="url">
         <value>${db.url}</value>
      </property>
      <property name="username">
         <value>${db.username}</value>
      </property>
      <property name="password">
         <value>${db.password}</value>
      </property>
      <!–
      <property name="initialSize">
         <value>2</value>
      </property>
      <property name="maxActive">
         <value>4</value>
      </property>
      <property name="minIdle">
         <value>2</value>
      </property>
      <property name="maxIdle">
         <value>4</value>
      </property>
      <property name="defaultAutoCommit">
         <value>false</value>
      </property>
      <property name="defaultTransactionIsolation">
         <value>${db.txn.isolation}</value>
      </property>
      <property name="maxWait">
         <value>${db.pool.wait.max}</value>
      </property>
      <property name="validationQuery">
         <value>${db.pool.validate.query}</value>
      </property>
      <property name="timeBetweenEvictionRunsMillis">
         <value>${db.pool.evict.interval}</value>
      </property>
      <property name="minEvictableIdleTimeMillis">
         <value>${db.pool.evict.idle.min}</value>
      </property>
      <property name="testOnBorrow">
         <value>${db.pool.validate.borrow}</value>
      </property>
      <property name="testOnReturn">
         <value>${db.pool.validate.return}</value>
      </property>
      <property name="testWhileIdle">
         <value>${db.pool.evict.validate}</value>
      </property>
      <property name="removeAbandoned">
         <value>${db.pool.abandoned.detect}</value>
      </property>
      <property name="removeAbandonedTimeout">
         <value>${db.pool.abandoned.time}</value>
      </property>
      <property name="poolPreparedStatements">
         <value>${db.pool.statements.enable}</value>
      </property>
      <property name="maxOpenPreparedStatements">
         <value>${db.pool.statements.max}</value>
      </property>
      –>
   </bean>

   <bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="transactionSynchronizationName" value="SYNCHRONIZATION_ALWAYS" />
      <property name="dataSource" ref="dataSource" />
   </bean>
   
</beans>

</blockcode>

The other file is:

test-component-context.xml
==========================
<blockcode>
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>

   <bean id="common-placeholder-configurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" abstract="true">
           <property name="valueSeparator">
            <null/>
        </property>
        <property name="ignoreUnresolvablePlaceholders">
            <value>true</value>
        </property>
        <property name="searchSystemEnvironment">
            <value>false</value>
        </property>       
    </bean>
   
    <bean id="ServiceRegistry" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value="org.alfresco.service.ServiceRegistry" />
    </bean>

    <bean id="scriptService"  class="org.mockito.Mockito" factory-method="mock">
       <constructor-arg value="org.alfresco.service.cmr.repository.ScriptService" />
    </bean>

    <bean id="messageService" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value="org.alfresco.repo.i18n.MessageService" />
    </bean>

    <bean id="TransactionService" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value="org.alfresco.service.transaction.TransactionService" />
    </bean>

    <bean id="PersonService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces">
            <value>org.alfresco.service.cmr.security.PersonService</value>
        </property>
        <property name="target">
            <ref bean="personService"/>
        </property>
        <property name="interceptorNames">
            <list>
                <idref local="PersonService_transaction"/>
                <idref local="AuditMethodInterceptor"/>
                <idref local="exceptionTranslator"/>
                <idref bean="PersonService_security"/>
            </list>
        </property>
    </bean>

    <bean id="PersonService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager">
            <ref bean="transactionManager"/>
        </property>
        <property name="transactionAttributes">
            <props>
                <prop key="*">${server.transaction.mode.default}</prop>
            </props>
        </property>
    </bean>

    <bean id="tenantService" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value=" org.alfresco.repo.tenant.TenantService" />
    </bean>

    <bean id="NamespaceService" class="org.alfresco.service.namespace.NamespaceServiceMemoryImpl" />

    <bean id="DictionaryService" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value=" org.alfresco.service.cmr.dictionary.DictionaryService" />
    </bean>

    <bean id="NodeService" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value=" org.alfresco.service.cmr.repository.NodeService" />
    </bean>

    <bean id="PolicyComponent" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value="org.alfresco.repo.policy.PolicyComponent" />
    </bean>
   
    <bean id="searchService" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value="  org.alfresco.service.cmr.search.SearchService" />
    </bean>

    <bean id="permissionService" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value="  org.alfresco.service.cmr.security.PermissionService" />
    </bean>

    <bean id="authorityDAO" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value="   org.alfresco.repo.security.authority.AuthorityDAO" />
    </bean>

    <bean id="bpm_engineRegistry" class="org.mockito.Mockito" factory-method="mock">
        <constructor-arg value="org.alfresco.repo.workflow.BPMEngineRegistry" />
    </bean>
   
    <bean id="workflowAdminService" class="org.mockito.Mockito" factory-method="mock">
      <constructor-arg value="org.alfresco.service.cmr.workflow.WorkflowAdminService" />
    </bean>

   <bean id="baseWorkflowEngineStatus" class="org.alfresco.repo.workflow.WorkflowEngineStatus" abstract="true" />

    <!– Authentication Util initialization –>
    <bean id="authenticationUtil"
        class="org.alfresco.repo.security.authentication.AuthenticationUtil">
        <property name="defaultAdminUserName">
            <value>admin</value>
        </property>
        <property name="defaultGuestUserName">
            <value>guest</value>
        </property>
    </bean>
</beans>
</blockcode>

Also alfresco-global.properties file is:

<blockcode>

###############################
## Common Alfresco Properties #
## Enterprise overlay         #
###############################

dir.root=C:/Alfresco/alf_data

alfresco.context=alfresco
alfresco.host=127.0.0.1
alfresco.port=8080
alfresco.protocol=http

share.context=share
share.host=127.0.0.1
share.port=8090
share.protocol=http

### database connection properties ###
#Changed the code so it would use H2 in memory.
db.driver=org.h2.Driver
#db.driver=org.gjt.mm.mysql.Driver
db.username=alfresco
db.password=alfresco
db.name=alfresco_00
db.url=jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000
#db.url=jdbc:mysql://localhost:3306/alfresco_00?useUnicode=yes&characterEncoding=UTF-8

### FTP Server Configuration ###
ftp.enabled=true
ftp.port=2121
ftp.ipv6.enabled=false

### RMI service ports ###
alfresco.rmi.services.port=50500
avm.rmi.service.port=0
avmsync.rmi.service.port=0
attribute.rmi.service.port=0
authentication.rmi.service.port=0
repo.rmi.service.port=0
action.rmi.service.port=0
deployment.rmi.service.port=0

### External executable locations ###
ooo.exe=C:/Alfresco/openoffice/App/openoffice/program/soffice.exe
ooo.enabled=false
ooo.port=8100
img.root=C:\\Alfresco\\imagemagick
img.coders=${img.root}\\modules\\coders
img.config=${img.root}\\config
img.gslib=${img.root}\\lib
img.exe=${img.root}\\convert.exe
swf.exe=C:/Alfresco/swftools/pdf2swf.exe
swf.languagedir=C:/Alfresco/swftools/japanese

jodconverter.enabled=true
jodconverter.officeHome=C:/Alfresco/openoffice/App/openoffice
jodconverter.portNumbers=8100

### Initial admin password ###
alfresco_user_store.adminpassword=209c6174da490caeb422f3fa5a7ae634

### E-mail site invitation setting ###
notification.email.siteinvite=false

### License location ###
dir.license.external=C:/Alfresco

### Solr indexing ###
index.subsystem.name=solr
dir.keystore=${dir.root}/keystore
solr.port.ssl=8443

### BPM Engine ###
system.workflow.engine.jbpm.enabled=false

### Replication ###
replication.enabled=true

</blockcode>

And lastly extra-test.properties contains:

<blockcode>
spaces.company_home.childname=app:company_home
spaces.store=workspace://SpacesStore

#These parameters are coming from sysadmin-parameter.properties file.
server.maxusers=-1
server.allowedusers=
server.allowWrite=true

server.transaction.mode.default=PROPAGATION_REQUIRED

alfresco.context=alfresco
#alfresco.host=${localname}
alfresco.host=localhost
alfresco.port=8080
alfresco.protocol=http

share.context=share
#share.host=${localname}
share.host=localhost
share.port=8080
share.protocol=http

# Share Site configuration.
#
# This property controls who has visibility of created share sites.
site.public.group=GROUP_EVERYONE

</blockcode>

The inspration came from the Activiti JUnit test where it is mocking many of the Alfresco services. However, now I am stuck at the error:

Caused by: org.xml.sax.SAXParseException: An element with the identifier "exceptionTranslator" must appear in the document.

I was wondering if there is a better context file for getting this thing going. Otherwise, I have to either mock or figure out the definitions for all the services I need.

Thanks.

Outcomes