2

I write test for my application:

public class CandidateServiceTest {

    @Autowired
    CandidateService candidateService;

    @BeforeClass
    public static void initialize() throws Exception{
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "test/BeanConfig.xml");//I think here I load context

        UtilMethods.createTestDb();

    }

    @Test
    public void add(){
        Candidate candidate = new Candidate();
        candidate.setName("testUser");
        candidateService.add(candidate);//NullPointerException  here
        List<Candidate> candidates = candidateService.findByName(candidate.getName());
        Assert.assertNotNull(candidates);
    }
}

in row

candidateService.add(candidate);//Null entity here   here

candidateService is null.

test/BeanConfig.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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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">

        <!-- Включаем опцию использования конфигурационных аннотаций (@Annotation-based configuration)-->
        <context:annotation-config />


        <context:component-scan base-package="com.epam.hhsystem.jpa" />
        <context:component-scan base-package="package com.epam.hhsystem.services" />

        <!-- Файл с настройками ресурсов для работы с данными (Data Access Resources) -->
        <import resource="data.xml" />

    </beans>

data.xml - info about hibernate,

class of CandidateService:

package com.epam.hhsystem.services;
     ...
    @Transactional
    @Service("candidateService")
    public class CandidateService {

        @Autowired
        private CandidateDao candidateDao;//package com.epam.hhsystem.jpa

        @Autowired
        private VacancyDao vacancyDao;//package com.epam.hhsystem.jpa

        @Autowired
        private SkillDao skillDao;//package com.epam.hhsystem.jpa

        @Autowired
        private EventDao eventDao;//package com.epam.hhsystem.jpa

        @Autowired 
        UtilService utilService;//package com.epam.hhsystem.services


        public void add(Candidate candidate) {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            String login = auth.getName();
            User user =  utilService.getOrSaveUser(login);
            candidate.setAuthor(user);
            candidateDao.add(candidate);
        }

        ....
    }

Can you help me?

UPDATE

I rewrite code so:

@ContextConfiguration(locations = {"classpath:/test/BeanConfig.xml"})
public class CandidateServiceTest extends AbstractTransactionalJUnit4SpringContextTests{

    @Autowired
    CandidateService candidateService;

    @BeforeClass
    public static void initialize() throws Exception{

        UtilMethods.createTestDb();

    }

    @Test
    public void add(){
        Candidate candidate = new Candidate();
        candidate.setName("testUser");
        candidateService.add(candidate);
        List<Candidate> candidates = candidateService.findByName(candidate.getName());
        Assert.assertNotNull(candidates);
    }
}

And I have so trace:

java.lang.NullPointerException
at com.epam.hhsystem.services.CandidateService.add(CandidateService.java:56)
at com.epam.hhsystem.services.CandidateService$$FastClassByCGLIB$$3796612d.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
at com.epam.hhsystem.services.CandidateService$$EnhancerByCGLIB$$afe33393.add(<generated>)
at com.epam.hhhsystem.services.CandidateServiceTest.add(CandidateServiceTest.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
gstackoverflow
  • 36,709
  • 117
  • 359
  • 710
  • Did you tell your JUnit to use Spring test runner? What annotations do you have on CandidateServiceTest? – Piotr Kołaczkowski Sep 23 '13 at 16:11
  • Small remark regarding your config `` is already implied by using a ``. And instead of multiple `` simply use a single one with a , seperated list of packages to scan. – M. Deinum Sep 23 '13 at 16:17
  • Your service assumes that there is an `Authentication` object, but there isn't one. You need to set one before your test starts, either in your `@Test` or by using a `@Before` method. – M. Deinum Sep 23 '13 at 16:37
  • It is not clear for me. Can you write code? – gstackoverflow Sep 23 '13 at 16:42

4 Answers4

3

Your testcase is written wrong. Use the framework don't work around it. Use Springs Test Support classes to load and autowire your testcase, instead of trying to work your way around it.

@ContextConfiguration(locations = {"classpath:/test/BeanConfig.xml"})
public class CandidateServiceTest extends AbstractTransactionalJUnit4SpringContextTests {

    @Autowired
    CandidateService candidateService;

    @Test
    public void add(){
        Candidate candidate = new Candidate();
        candidate.setName("testUser");
        candidateService.add(candidate);//NullPointerException  here
        List<Candidate> candidates = candidateService.findByName(candidate.getName());
        Assert.assertNotNull(candidates);
    }
}

I strongly suggest a read of the Spring Reference Guide and in this case especially the section covering testing.

Next to not using the framework properly you aren't setting your initial state properly. You are writing a unit/integration test and your CandidateService implementation expects that a Spring Security Authentication object is available. You aren't setting one before your test is run so that will result in a NullPointerException.

Add a @Before method which will set it before your test method and an @After method which cleans up after that. (Or do it in your test method but remember to cleanup properly!).

@Before
public void setup() {
    TestingAuthenticationToken testToken = new TestingAuthenticationToken("testUser", "");
    SecurityContextHolder.getContext().setAuthentication(testToken);
}

@After
public void cleanUp {
    SecurityContextHolder.clearContext();
}
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
2

I don't see the annotation for test class that you put here. Normally, to run test class in Spring context, you need to use following annotation:

@RunWith(SpringJUnit4ClassRunner.class) 
// This will run necessary job to load the context and inject bean into your test
@ContextConfiguration("classpath:/test-bundle-context.xml") 
// This specify the configuration used, you can use the java-config style as well (but only for Spring 3.1)
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true) 
// If you want to test the transaction, otherwise, this is not necessary
@Transactional(propagation = Propagation.SUPPORTS) 
// depend on your test natural, you can set difference propagation.

Component scan doesn't help anything in your test.

Maven dependency:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>3.1.0.RELEASE</version>
    <scope>test</scope>
</dependency>
Casper Ngo
  • 343
  • 2
  • 8
1

I guess your BeanConfig.xml is wrong, because it contains "package":

 <context:component-scan base-package="package com.epam.hhsystem.services" />

Change it to:

// package removed     
<context:component-scan base-package="com.epam.hhsystem.services" />

Does it help?

Ernestas Kardzys
  • 1,719
  • 2
  • 16
  • 21
0

I was having a similar problem and the cause turned out to be none of the answers above. Turns out my IDE had inserted import org.junit.Test instead of import org.testng.annotations.Test. Trivial but very hard to track down.

Alex R
  • 11,364
  • 15
  • 100
  • 180