JUnit test cases for Spring Service Layer
Solution 1
Add the Spring JUnit class runner. You should also use the @Test annotations instead of extending TestCase.
e.g.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
Solution 2
This is how I Create My ServiceTest Hope this will help you
Just want to add some idea and im not sure if it is a best practice or not so correct me if theres something wrong.
-
MYPROJECT
-src
--hibernate.cfg.xml
-test
--TestPackage
---BaseServiceTest.class
---BlogspotServiceTest.class
-web
--WEB-INF
---blogspot-servlet-test.xml
---jdbc-test.properties
in my case I used my blogspot-servlet-test.xml to call or to create the datasource and other configuration needed.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- .... some bean configuration -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="file:web/WEB-INF/jdbc-test.properties"/>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- DAO'S -->
<bean id="blogspotDAO" class="package.BlogspotDAOImpl"/>
<!-- SERVICES -->
<bean id="blogspotService" class="package.BlogspotServiceImpl"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
MY jdbc-test.properties file
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQL5Dialect
jdbc.databaseurl=jdbc:mysql://localhost:port/dbschemaname
jdbc.username=root
jdbc.password=
For hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd//hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="somePackage.entity.Author"/>
<!-- Other Entity Class to be mapped -->
</session-factory>
</hibernate-configuration>
and i created BaseClass for me to lessen creating of multiple @SpringApplicationContext annotation and it is also use to create common configuration needed in testing other test class,you just need to extends it.
@SpringApplicationContext({"file:web/WEB-INF/blogspot-servlet-test.xml"})
public class BaseServiceTest extends UnitilsJUnit4 {
}
i used @SpringApplicationContext to load the datasource and other bean configurations on my BaseClass from my spring configuration and this is how i implement it.
Below : see Spring-Unitils Tutorial for more details
public class BlogspotServiceTest extends BaseServiceTest{
@Mock //mock this object
@InjectInto(property = "blogspotDAO") //inject the dao to the test object
@SpringBean("blogspotDAO") //it is most likely @Autowired annotation
private BlogspotDAO blogspotDAOMock;
@TestedObject //annotate that this object is for test
@SpringBean("blogspotService")
private BlogspotService blogspotServiceMock;
@Test
public void testAddBlogSpot() {
assertNotNull("BlogspotService Not null",blogspotServiceMock); //test if blogspotServiceMock is not null
}
}
NOTE: please create unitils.properties and unitils-local.properties inside TestPackage to be able to run the program.
For @SpringBean explanation and other annotation please read :
OTUser
Updated on October 02, 2020Comments
-
OTUser over 3 years
I am trying to configure JUnit and write test cases for Service layer of Spring 3.2 MVC application. I couldnt find much information on how to configure the JUnit from scratch and make it work for Spring service layer. here is my problem
I dont really know what version of junit to be used so i just grabbed the latest version
Maven junit dependancy
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
My service Class
@Service public class AuthService implements IAuthService, ApplicationContextAware, org.springframework.context.ApplicationListener<org.springframework.context.event.ContextRefreshedEvent> { public Collection<? extends String> addCommandPermissions(Session session, CommandMetadata command) { Set<String> result = new HashSet<String>(); String commandName = command.getBeanName(); String defaultAdministerPermission = command.getAdministerPermission() String defaultExecutePermission = command.getExecutePermission() String overrideAdminPermission = null; String overrideExecPermission = null; String finalAdministerPermission = overrideAdminPermission == null ? defaultAdministerPermission : overrideAdminPermission; command.setAdministerPermission(finalAdministerPermission); result.add(finalAdministerPermission); String finalFxecutePermission = overrideExecPermission == null ? defaultExecutePermission : overrideExecPermission; command.setExecutePermission(finalFxecutePermission); result.add(finalFxecutePermission); try { session.saveOrUpdate(command); session.flush(); } finally { // TODO - more swallowed exceptions. } return result; } // some other methods }
My Test Class(used groovy partially)
import junit.framework.TestCase; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpSession; import org.springframework.test.context.ContextConfiguration; import com.dc.core.security.service.impl.AuthService import com.dc.core.behavior.command.model.impl.CommandMetadata; import org.hibernate.SessionFactory import org.hibernate.classic.Session @ContextConfiguration(locations = "file:WebContent/WEB-INF/applicationContext.xml") public class AuthServiceTest extends TestCase { @Autowired private AuthService authService; @Autowired private MockHttpSession mockHttpSession; @Autowired ApplicationContext appContext @Autowired SessionFactory sessionFactory private Session mockHibernateSession = Mockito.mock(org.hibernate.classic.Session.class); private CommandMetadata commandMetadata = new CommandMetadata(); public void setUp() { appContext.getBeanFactory().registerScope("request", new RequestScope()) MockHttpServletRequest request = new MockHttpServletRequest() ServletRequestAttributes attributes = new ServletRequestAttributes(request) RequestContextHolder.setRequestAttributes(attributes) CurrentRequestProperties currentRequestProperties = appContext.getBean("currentRequestProperties") session = sessionHandler.initiateSession(sessionFactory, currentRequestProperties) } public void testAddCommandPermissions() { commandMetadata.beanName = "TestBean" commandMetadata.administerPermission = "TestBean.administer" commandMetadata.executePermission = "TestBean.execute" Collection<String> results = authorizationService.addCommandPermissions(session, commandMetadata); assertTrue(results.contains("TestBean.administer")) } public void testCanary() { assertTrue(true); } }
When I run my test case am getting the below error java.lang.NullPointerException: Cannot invoke method getBeanFactory() on null object
I think cause of the issue is appContext is not injected properly hence am getting NPE. But I couldnt solve this issue. I really appreciate someone's help on this
-
G. Demecki over 9 yearsYour post doesn't answer original question. And besides: Unitils development is almost abandoned, so IMHO do not use it.