Java Spring 服务层的 JUnit 测试用例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24091778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 10:06:53  来源:igfitidea点击:

JUnit test cases for Spring Service Layer

javaunit-testingspring-mvcgroovyjunit4

提问by RanPaul

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

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

I dont really know what version of junit to be used so i just grabbed the latest version

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

Maven junit dependancy

Maven junit 依赖

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

我的测试课(部分使用了 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);
    }
}

When I run my test case am getting the below error java.lang.NullPointerException: Cannot invoke method getBeanFactory() on null object

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

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

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

采纳答案by Steven

Add the Spring JUnit class runner. You should also use the @Test annotations instead of extending TestCase.

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

e.g.

例如

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

回答by Secondo

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
  • MYPROJECT
    - src
    --hibernate.cfg.xml
    - test
    --TestPackage
    ---BaseServiceTest.class
    ---BlogspotServiceTest.class
    - web
    --WEB-INF
    ---blogspot-servlet-test.xml
    ---jdbc-test 。特性

in my case I used my blogspot-servlet-test.xml to call or to create the datasource and other configuration needed.

在我的例子中,我使用我的 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>

MY jdbc-test.properties file

我的 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=

For hibernate.cfg.xml

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

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

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

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

Below : see Spring-Unitils Tutorialfor more details

下面: 有关更多详细信息,请参阅Spring-Uni​​tils 教程

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.

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

For @SpringBean explanation and other annotation please read :

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

Unitils-EasyMock

Unitils-EasyMock