Spring testing and maven

这一生的挚爱 提交于 2019-12-19 09:53:50

问题


I'm trying to test my Spring web app but i have some problems.

I added a test class in my maven

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void testName() throws Exception {
        List<UserEntity> userEntities = userService.getAllUsers();

        Assert.assertNotNull(userEntities);
    }
}

But i got a NullPointerException on userService when i try to run this test. IntelliJ say "Could not autowire. No beans of 'UserService' type found. After adding @RunWith(SpringJUnit4ClassRunner.class) , i got this exception

java.lang.IllegalStateException: Neither GenericXmlContextLoader nor AnnotationConfigContextLoader was able to detect defaults, and no ApplicationContextInitializers were declared for context configuration

How can i solve it ? And i think i need to run this test on my tomcat server but how can i deploy for testing with IntelliJ ? (like command 'mvn clean install tomcat7:run-war-only')


回答1:


You have to provide the location of your Spring context file to be initialized before the test starts.

Test class

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration(locations = { "classpath:META-INF/your-spring-context.xml" })
public class UserServiceTest extends AbstractJUnit4SpringContextTests {

    @Autowired
    private UserService userService;

    @Test
    public void testName() throws Exception {
        List<UserEntity> userEntities = userService.getAllUsers();

        Assert.assertNotNull(userEntities);
    }
}

your-spring-context.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="userService" class="java.package.UserServiceImpl"/>

</beans>



回答2:


Depending on what you are trying to achieve via testing, you need to either write a unit test or a Spring integration test.

In the latter case you need to change your code to:

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

   @Autowired
   private UserService userService;

    //test whatever
}

When performing such integration tests, you will probably want to hook into the Spring Profile mechanism. By leveraging it, you will be able to reuse the same configuration you use in your production code while selectively replacing certain beans (for example by swapping the production datasource with an in-memory database).

If you are using Spring 4, then Conditional would give you even more flexibility.

I suggest you give this part of the Spring test documentation a good read to get an overview of what Spring integration tests can do for you.


The case you have presented I'm not sure warrants itself for an integration test (more details on what UserService actually does would give a clearer picture).

For example if UserService uses a UserDao and then performs some custom logic on the results from the dao, creating a unit test for UserService with a mocked UserDao would be a good option.

If you are using constructor injection to supply the dao to the service, then construction of the service is a no-brainer. If you are using field injection via @Autowired (which you shouldn't be if you can avoid it), then you would need to inject the mock via reflection. A super utility for that is Spring's ReflectionTestUtils

Then you could create an integration test for UserDao which would test it's ability to correctly read data from the database.


Finally note that the comments above are independent of the how you run the tests (IDE or Maven). If it's configured correctly, the tools will happilly run it




回答3:


I am not sure, but think that you need to add locations property to ContextConfiguration annotation where you could specify the xml file where all of the beans exist. Moreover, I guess the operation of fetching all users is database related so it is good to add TransactionConfiguration annotation. Thus, you should have something like this:

@ContextConfiguration(locations = {"classpath:spring-config-junit.xml"}) @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)



来源:https://stackoverflow.com/questions/26055876/spring-testing-and-maven

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!