简体   繁体   中英

Autowired failed with null result when running test with TestNG and Spring context

I am construct the spring using maven , I dont know where i am wrong, spring ioc i have add this beans but still appear the follow error

[TestNG] Running:
C:\Users\lw\AppData\Local\Temp\testng-eclipse-280706424\testng-customsuite.xml

null
[Utils] Attempting to create D:\lw\workspace\spring\test-output\Default    suite\Default test.xml
[Utils]   Directory D:\lw\workspace\spring\test-output\Default suite exists:   true
FAILED: testIOC
java.lang.NullPointerException
at com.syz.test01.AppTest.testIOC(AppTest.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at   org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.j ava:100)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:646)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:811)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1137)
at  org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129 )
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:753)
at org.testng.TestRunner.run(TestRunner.java:607)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:368)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:363)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:321)
at org.testng.SuiteRunner.run(SuiteRunner.java:270)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1284)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1209)
at org.testng.TestNG.runSuites(TestNG.java:1124)
at org.testng.TestNG.run(TestNG.java:1096)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:236)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:81)


===============================================
Default test
Tests run: 1, Failures: 1, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 1, Failures: 1, Skips: 0
===============================================

web.xml

 <web-app>
 <display-name>Archetype Created Web Application</display-name>
 </web-app>

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"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/context   http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<context:component-scan base-package="com.syz.test01" />
</beans>

Person.java

package com.syz.test01;
@Component
public class Person {
public String name = "zhangsan";

public String age = "1";

public String getName() {

    return name;

}

public void setName(String name) {

    this.name = name;

}

public String getAge() {

    return age;

}

public void setAge(String age) {

    this.age = age;

    }
}

App.java

package com.syz.test01;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@Component
public class App {
@Autowired
public Person person;

public Person getPerson() {
    return person;
}

public void setPerson(Person person) {
    this.person = person;
}

public  void testIOC()

{
    System.out.println("hello");
    }
}

Apptest.java

package com.syz.test01;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.testng.annotations.Test;
@ContextConfiguration(locations = { "classpath*:applicationContext.xml" })
public class AppTest {
@Autowired
public App app ;

public App getApp() {
    return app;
}
public void setApp(App app) {
    this.app = app;
}
@Test
public void testIOC() {
    System.out.println(app);
    System.out.println(app.getPerson().getName());
    }
}

Person.java

package com.syz.test01;
@Component
public class Person {
public String name = "zhangsan";

public String age = "1";

public String getName() {

    return name;

}

public void setName(String name) {

    this.name = name;

}

public String getAge() {

    return age;

}

public void setAge(String age) {

    this.age = age;

    }
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.spring</groupId>
<artifactId>spring</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>spring Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
</dependency>
<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.3.1.RELEASE</version>
</dependency>
<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.1.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>spring</finalName>
</build>
</project>

picture enter image description here

Because your beans are loaded by the "component-scan", you must annotate your components with @Component :

@Component
public class Person {
....
}

and

@Component
public class App {
....
}

UPDATE:

The test class AppTest.java must be annotated with @ContextConfiguration :

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

make sure TestNG can see and load the file applicationContext.xml by correcting its path.

UPDATE 2:

To get works, you might need to add dependency to spring-test in your pom.xml:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.4.RELEASE</version>
    <scope>test</scope>
</dependency>

UPDATE 3:

Add this to AppTest.java :

@org.junit.runner.RunWith(org.springframework.test.context.junit4.SpringJUnit4ClassRunner.class)

This instruct junit to execute test as a Spring test.

Note that SpringJUnit4ClassRunner only works with junit 4.5+, so update your dependency of junit to latest:

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

COMPLETE

Here is complete working AppTest.java . Note that some testng annotations have been replaced by junit for compatibility with Spring test framework.

package com.syz.test01;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@org.junit.runner.RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:applicationContext.xml" })
public class AppTest{
    @Autowired
    public App app;

    public App getApp() {
        return app;
    }
    public void setApp(App app) {
        this.app = app;
    }
    @org.junit.Test
    public void testIOC() {
        System.out.println(app);
        System.out.println(app.getPerson().getName());
    }
}

You aren't giving any values to your Person class in your app class. So that means in AppTester, when it calls app.getPerson it is sending a null value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM