7

I'm trying to test the correct information given from DB using the services and the correct logic of the methods. In this simple example, I'm only using the statement assertEquals to compare the id given for the roleService, but I'm still getting errors. I have the following code:

[UPDATED]

Test method:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = { "classpath:applicationContext.xml" })
@Transactional
@WebAppConfiguration
@ComponentScan(basePackages ={ "com.project.surveyengine" },
            excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Configuration.class) ,
                              @ComponentScan.Filter(type = FilterType.ANNOTATION, value = WebConfig.class)})
public class RoleServiceTest {

@Configuration
    static class ContextConfiguration {    
        @Bean
        public RoleService roleService() {
            RoleService roleService = new RoleService();
            // set properties, etc.
            return roleService;
        }
    }

    private final LocalServiceTestHelper helper =
            new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()
                    .setDefaultHighRepJobPolicyUnappliedJobPercentage(100));

    private Closeable closeable;

    @Before
    public void setUp() {
        helper.setUp();
        ObjectifyService.register(Role.class);
        closeable = ObjectifyService.begin();
    }

    @After
    public void tearDown() {
        closeable.close();
        helper.tearDown();
    }

    @Autowired
    private RoleService roleService;

    @Test
    public void existsRole() throws Exception{
        Role role = roleService.getByName("ROLE_ADMIN");
        assertEquals("Correct test", Long.valueOf("5067160539889664"), role.getId());
    }

}

RoleService is the service class that consult Database information using objectifyService from Google App Engine.

applicationContext.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:context="http://www.springframework.org/schema/context"
       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">

    <context:annotation-config /> 

    <context:component-scan base-package="com.project.surveyengine.config"/>

    <!--Controllers-->
    <bean id="inboxController" class="com.project.surveyengine.controller.InboxController" autowire="byType"></bean>
    <bean id="mailController" class="com.project.surveyengine.controller.MailController" autowire="byType"></bean>
    <bean id="loginController" class="com.project.surveyengine.controller.LoginController" autowire="byType"></bean>
    <bean id="initController" class="com.project.surveyengine.controller.InitController" autowire="byType"></bean>

    <!--Services-->
    <bean id="answerService" class="com.project.surveyengine.service.impl.AnswerService" autowire="byType"></bean>
    <bean id="blobService" class="com.project.surveyengine.service.impl.BlobService" autowire="byType"></bean>
    <bean id="mailService" class="com.project.surveyengine.service.impl.MailService" autowire="byType"></bean>
    <bean id="caseService" class="com.project.surveyengine.service.impl.CaseService" autowire="byType"></bean>
    <bean id="roleService" class="com.project.surveyengine.service.impl.RoleService" autowire="byType"></bean>
</beans>

Into the com.project.surveyengine.config I have the folliwing three classes:

1)

public class MyXmlWebApplicationContext extends XmlWebApplicationContext {
    protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
        super.initBeanDefinitionReader(beanDefinitionReader);
        if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) {
            beanDefinitionReader.setValidating(false);
            beanDefinitionReader.setNamespaceAware(true);
        }
    }
}

2)

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter{    
  @Bean
  UrlBasedViewResolver resolver(){
    UrlBasedViewResolver resolver = new UrlBasedViewResolver();
    resolver.setPrefix("/views/");
    resolver.setSuffix(".jsp");
    resolver.setViewClass(JstlView.class);
    return resolver;
  }

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/statics/**").addResourceLocations("/statics/");
  }    
}

3)

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityContext extends WebSecurityConfigurerAdapter {    
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/statics/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .formLogin()
                //...more code
    }
}

I'm getting this errors:

Dec 20, 2016 4:40:03 PM com.google.appengine.api.datastore.dev.LocalDatastoreService init INFO: Local Datastore initialized: Type: High Replication Storage: In-memory

java.lang.NullPointerException at com.project.surveyengine.service.impl.RoleServiceTest.existsRole(RoleServiceTest.java:111)

RoleServiceTest.java:111 = assertEquals("Correct test", Long.valueOf("5067160539889664"), role.getId());
9
  • 1
    My personal opinion is that first of all you need to decide what kind of test you want. Is it really a sort of an integration test? Does it make sense to connect to the real DB and have all the associated boilerplate configured so you can verify some complex logic in your module? Or is it just a unit test to verify that your service behaves as expected? Case in which you can simply mock the service's dependencies (mockito, easy mock, etc) and just instantiate it and verify the output of its methods. I can't tell from your description but to me it seems the latter, hence my suggestion. Commented Dec 7, 2016 at 17:00
  • Yes, previously I was using Mockito, but I have some methods that I need to mock several repositories, so this becomes a complex job. The idea is checks the expected result from a complex module, but also combined using real information from DB. That's why I'm using the services into the test. Commented Dec 7, 2016 at 17:10
  • The exception is really straightforward - your test can't find defaultServletHandlerMapping bean. That happens because of WebConfig class, so, you should add it to the filtering: Filter(type = FilterType.ANNOTATION, value = Configuration.class), Filter(type = FilterType.ANNOTATION, value = WebConfig.class) }) Commented Dec 8, 2016 at 7:52
  • But overall I totally agree with @Morfic . You should never use real database data for test purposes. If you want to have an integration tests embedded database (H2, Derby) is a nice option. You should keep junit test small and clear. The test should ideally test the class only but not the whole application logic. Commented Dec 8, 2016 at 7:55
  • @Enigo Even so, when I add it to the filtering, it gives to me the same error. Commented Dec 15, 2016 at 14:36

1 Answer 1

3
+25

Did you try to add @WebAppConfiguration as suggested in the documentation http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/context/web/WebAppConfiguration.html ?

I'd wirte your test code in this way

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = { "classpath:applicationContext.xml" })
@TransactionConfiguration(transactionManager="txMgr", defaultRollback=false)
@Transactional
@WebAppConfiguration
@ComponentScan(basePackages ={ "com.project.surveyengine" }, excludeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Configuration.class) })
public class RoleServiceTest {

    @Autowired
    private RoleService roleService;

    @Test
    public void existsRole() throws Exception{
        Role role = roleService.getByName("ROLE_ADMIN");
        assertEquals("Correct test", Long.valueOf("5067160539889664"), role.getId());
    }

}

as you can see i added the annotation @WebAppConfiguration too

I hope this can help you

Sign up to request clarification or add additional context in comments.

7 Comments

I get this error: java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig
This is related to the fact that you don't have some lib under your classpath; are yuo using maven? you can add servlet API dependency to the pom.xml
Yes I'm using maven. And also I added the servlet-api dependency, so the error is the same.
Can you post the details of the servlet-api dependency you've added, so it can be verified as correct?
Sure @Adam. <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency>
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.