Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: change "widely use" to "widely used".

...

Info
titleSource Code

The code for this tutorial is located in the "tutorial-service" module of the appfuse-demos project on Google Code. Use the following command to check it out from Subversion:

No Format

svn checkout http://appfuse-demos.googlecode.com/svn/trunk/tutorial-service

...

Info
titleTransactions

All service.*Manager beans will automatically be configured by Spring to wrap PROPOGATION_REQUIRED transactions around their method executions. This is done by the following Spring AOP configuration in appfuse-service.jar.

No Format

<aop:config>     
    ...     
    <aop:advisor id="managerTx" advice-ref="txAdvice"          
        pointcut="execution(* *..service.*Manager.*(..))" order="2"/> 
</aop:config>

...

Hibernate:

Code Block
languagexml

<bean id="personManager" class="org.appfuse.service.impl.GenericManagerImpl">     
    <constructor-arg>         
        <bean class="org.appfuse.dao.hibernate.GenericDaoHibernate" autowire="byType">             
            <constructor-arg value="org.appfuse.tutorial.model.Person"/>         
        </bean>     
    </constructor-arg> 
</bean>

...

If you wrote the PersonDao interface and implementation in the previous tutorial, you'll want to use the following for your personManager bean definition. If you don't, your PersonDaoTest will fail because there's no longer an exposed personDao bean.

Code Block
languagexml

<bean id="personManager" class="org.appfuse.service.impl.GenericManagerImpl">     
    <constructor-arg ref="personDao"/> 
</bean>

Once you've created a personManager bean definition, you can use this bean on an object by adding the following setter method:

Code Block
languagejava

public void setPersonManager(GenericManager<Person, Long> personManager) {
    this.personManager = personManager; 
}

...

First off, create a PersonManager interface (in the src/main/java/**/service directory - you may need to create this first) and specify the finder method for any implementation classes.

Code Block
languagejava

package org.appfuse.tutorial.service;

import org.appfuse.service.GenericManager;
import org.appfuse.tutorial.model.Person;

import java.util.List;

public interface PersonManager extends GenericManager<Person, Long> {
    List<Person> findByLastName(String lastName);
}

...

You can write your own mock objects, but here you are going to use jMock. Another widely use used Mock Object library is EasyMock.

...

Create PersonManagerImplTest in src/test/java/**/service/impl:

Code Block
languagejava

package org.appfuse.tutorial.service.impl;

import org.appfuse.service.impl.BaseManagerMockTestCase;
import org.appfuse.tutorial.dao.PersonDao;
import org.appfuse.tutorial.model.Person;
import org.appfuse.tutorial.service.impl.PersonManagerImpl;
import org.jmock.Expectations;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.*;

public class PersonManagerImplTest extends BaseManagerMockTestCase {
    private PersonManagerImpl manager = null;
    private PersonDao dao = null;

    @Before
    public void setUp() {
        dao = context.mock(PersonDao.class);
        manager = new PersonManagerImpl(dao);
    }

    @After
    public void tearDown() {
        manager = null;
    }

    @Test
    public void testGetPerson() {
        log.debug("testing get...");

        final Long id = 7L;
        final Person person = new Person();

        // set expected behavior on dao
        context.checking(new Expectations() {{
            one(dao).get(with(equal(id)));
            will(returnValue(person));
        }});

        Person result = manager.get(id);
        assertSame(person, result);
    }

    @Test
    public void testGetPersons() {
        log.debug("testing getAll...");

        final List persons = new ArrayList();

        // set expected behavior on dao
        context.checking(new Expectations() {{
            one(dao).getAll();
            will(returnValue(persons));
        }});

        List result = manager.getAll();

        assertSame(persons, result);
    }

    @Test
    public void testSavePerson() {
        log.debug("testing save...");

        final Person person = new Person();
        // enter all required fields
        
        // set expected behavior on dao
        context.checking(new Expectations() {{
            one(dao).save(with(same(person)));
        }});

        manager.save(person);
    }

    @Test
    public void testRemovePerson() {
        log.debug("testing remove...");

        final Long id = -11L;

        // set expected behavior on dao
        context.checking(new Expectations() {{
            one(dao).remove(with(equal(id)));
        }});

        manager.remove(id);
    }
}

...

Create PersonManagerImpl.java in src/main/java/**/service/impl.

Code Block
languagejava

package org.appfuse.tutorial.service.impl;

import org.appfuse.tutorial.dao.PersonDao;
import org.appfuse.tutorial.model.Person;
import org.appfuse.tutorial.service.PersonManager;
import org.appfuse.service.impl.GenericManagerImpl;

import java.util.List;

public class PersonManagerImpl extends GenericManagerImpl<Person, Long> implements PersonManager {
    PersonDao personDao;

    public PersonManagerImpl(PersonDao personDao) {
        super(personDao);
        this.personDao = personDao;
    }

    public List<Person> findByLastName(String lastName) {
        return personDao.findByLastName(lastName);
    }
}

...

There are two ways to register your personManager bean at this point: 1) using a @Service annotation or 2) with XML. To use annotations, simply add @Service("personManager") as a class level parameter:

Code Block
languagejava

import org.springframework.stereotype.Service;

@Service("personManager")
public class PersonManagerImpl extends GenericManagerImpl<Person, Long> implements PersonManager {
Note

If you registered the personDao using the @Repository("personDao") annotation instead of src/main/webapp/WEB-INF/applicationContext.xml file you will need to auto-wire the PersonDao variable in the PersonManagerImpl class:

No Format

@Autowired
public PersonManagerImpl(PersonDao personDao) {
    super(personDao);
    this.personDao = personDao;
}

If you'd prefer to use XML, open your src/main/webapp/WEB-INF/applicationContext.xml file and replace the personManager bean with the following:

Code Block
languagexml

<bean id="personManager" class="org.appfuse.tutorial.service.impl.PersonManagerImpl">
    <constructor-arg ref="personDao"/>
</bean>
Note

The Web application tutorials assume that you will be using the GenericManager. If you follow them after making this change, you will need to change all the references in their code from the GenericManager to your new PersonManager interface. For example:

No Format

@Autowired
private PersonManager personManager;

...

Edit your pom.xml file in your project's top level directory. Add EasyMock as a dependency in the <dependencies> element:

Code Block
languagexml

<dependencies>
    ...
    <dependency>
        <groupId>org.easymock</groupId>
        <artifactId>easymock</artifactId>
        <version>2.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

...

Edit the PersonManagerImplTest class you wrote above so it looks as follows:

Code Block
languagejava

package org.appfuse.tutorial.service.impl;

import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.appfuse.tutorial.dao.PersonDao;
import org.appfuse.tutorial.model.Person;
import org.appfuse.tutorial.service.impl.PersonManagerImpl;

import java.util.ArrayList;
import java.util.List;

import static org.easymock.EasyMock.*;

public class PersonManagerImplTest extends TestCase {
    private final Log log = LogFactory.getLog(PersonManagerImplTest.class);
    private PersonManagerImpl manager = null;
    private PersonDao dao = null;
    private Person person = null;

    protected void setUp() throws Exception {
        log.debug("setUpDao for PersonManagerImplTest");
        dao = createStrictMock(PersonDao.class);
        manager = new PersonManagerImpl((PersonDao) dao);
    }

    public void testGetPerson() {
        log.debug("testing getPerson");

        Long id = 7L;
        person = new Person();

        // set expected behavior on dao
        expect(dao.get(id)).andReturn(person);
        replay(dao);

        Person result = manager.get(id);
        assertSame(person, result);
        verify(dao);
    }

    public void testGetPersons() {
        log.debug("testing getPersons");

        List people = new ArrayList();

        // set expected behavior on dao
        expect(dao.getAll()).andReturn(people);
        replay(dao);

        List result = manager.getAll();
        assertSame(people, result);
        verify(dao);
    }

    public void testGetByLastName() {
        log.debug("testing getByLastName");

        List people = new ArrayList();
        String lastName = "Smith";

        // set expected behavior on dao
        expect(dao.findByLastName(lastName)).andReturn(people);
        replay(dao);

        List result = manager.findByLastName(lastName);
        assertSame(people, result);
        verify(dao);
    }

    public void testSavePerson() {
        log.debug("testing savePerson");

        person = new Person();

        // set expected behavior on dao
        expect(dao.save(person)).andReturn(person);
        replay(dao);

        manager.save(person);
        verify(dao);
    }

    public void testRemovePerson() {
        log.debug("testing removePerson");

        Long id = 11L;
        person = new Person();

        // set expected behavior on dao
        dao.remove(id);
        replay(dao);

        manager.remove(id);
        verify(dao);
    }
}

...