【问题标题】:JUnit test cases for Spring Service LayerSpring Service Layer 的 JUnit 测试用例
【发布时间】:2014-06-06 22:53:14
【问题描述】:

我正在尝试为 Spring 3.2 MVC 应用程序的服务层配置 JUnit 并编写测试用例。我找不到太多关于如何从头开始配置 JUnit 并使其适用于 Spring 服务层的信息。这是我的问题

我真的不知道要使用哪个版本的junit,所以我只是抓住了最新版本

Maven junit 依赖

 <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>

我的服务类

@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
}

我的测试类(部分使用 groovy)

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);
    }
}

当我运行我的测试用例时,出现以下错误 java.lang.NullPointerException:无法在 null 对象上调用方法 getBeanFactory()

我认为问题的原因是 appContext 没有正确注入,因此我得到了 NPE。但我无法解决这个问题。我真的很感谢有人在这方面的帮助

【问题讨论】:

  • 这只是一个猜测,但您不需要像 @RunWith(SpringJUnit4ClassRunner.class) 这样的测试类吗?

标签: java unit-testing spring-mvc groovy junit4


【解决方案1】:

添加 Spring JUnit 类运行器。您还应该使用 @Test 注释而不是扩展 TestCase。

例如

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})

【讨论】:

    【解决方案2】:

    这就是我创建我的 ServiceTest 的方式希望这会对你有所帮助

    只是想添加一些想法,我不确定这是否是最佳实践,或者如果有什么问题,我不那么纠正我。

    • 我的项目
      -src
      --hibernate.cfg.xml
      -测试
      --TestPackage
      ---BaseServiceTest.class
      ---BlogspotServiceTest.class
      -网络
      --WEB-INF
      ---blogspot-servlet-test.xml
      ---jdbc-test.properties

    在我的例子中,我使用我的 blogspot-servlet-test.xml 来调用或创建所需的数据源和其他配置。

    <?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>
    

    我的 jdbc-test.properties 文件

    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.dialect=org.hibernate.dialect.MySQL5Dialect
    jdbc.databaseurl=jdbc:mysql://localhost:port/dbschemaname
    jdbc.username=root
    jdbc.password=
    

    对于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>
    

    我为我创建了 BaseClass 以减少创建多个 @SpringApplicationContext 注释,它也用于创建测试其他测试类所需的通用配置,你只需要扩展它。

    @SpringApplicationContext({"file:web/WEB-INF/blogspot-servlet-test.xml"})
    public class BaseServiceTest extends UnitilsJUnit4 {
    }
    

    我使用 @SpringApplicationContext 从我的 spring 配置中加载我的 BaseClass 上的数据源和其他 bean 配置,这就是我实现它的方式。

    以下:见Spring-Unitils Tutorial 了解更多

    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
        }
    }
    

    注意:请在 TestPackage 中创建 unitils.properties 和 unitils-local.properties 以便能够运行程序。

    @SpringBean 解释和其他注释请阅读:

    Unitils-EasyMock

    【讨论】:

    • 您的帖子没有回答原始问题。此外:Unitils 的开发几乎被放弃了,所以恕我直言,不要使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 2018-02-23
    • 2018-02-25
    • 1970-01-01
    相关资源
    最近更新 更多