2012-11-23 42 views
1

UPDATE返回NullPointerException異常25-11-2012春JUnit測試一直對我的服務類

嗨看來我的上下文文件是錯誤的「類路徑」他們必須在測試類路徑中。我通過將一個名爲resources的文件夾添加到src/test /文件夾來解決此問題。在這裏我可以把我的應用程序上下文。我也從測試中刪除了@TestExecutionListeners。我還需要爲javax/servlet/serlvetException等的我的pom文件添加一些依賴關係。如果有人有興趣,我的代碼可以在Github的分支issue9下看到。


問題[解決]

我已經做了簡單的應用程序,通過使用彈簧3我已經作出其使用DAO類的東西映射到和從數據庫服務等級,通過使用簡單的JDBC模板。

我的問題是,當我試圖對這些類進行集成測試時,它返回一個NullPointerException(請參閱Stacktrace)。這真的很煩人,因爲我似乎無法找到答案,所以我希望你們能幫助我。下面我已經發布了我所有的不同文件。

堆棧跟蹤

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.115 sec <<< FAILURE! 
test(dk.martinrohwedder.blog.test.ArticleServiceTest) Time elapsed: 0.009 sec <<< ERROR! 
java.lang.NullPointerException 
at dk.martinrohwedder.blog.service.ArticleService.getFiveLastArticles(ArticleService.java:30) 
at dk.martinrohwedder.blog.test.ArticleServiceTest.test(ArticleServiceTest.java:57) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:601) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30) 
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.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
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:300) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53) 
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123) 
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:601) 
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164) 
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110) 
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175) 
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107) 
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68) 

ArticleServiceTest

package dk.martinrohwedder.blog.test; 

import dk.martinrohwedder.blog.domain.Article; 
import dk.martinrohwedder.blog.service.ArticleService; 
import java.util.ArrayList; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 
import static org.junit.Assert.*; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.TestExecutionListeners; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.transaction.TransactionConfiguration; 
import org.springframework.transaction.annotation.Transactional; 
/** 
* 
* @author Martin Rohwedder 
*/ 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"classpath:test-context.xml"}) 
@TestExecutionListeners 
@TransactionConfiguration(defaultRollback = true) 
@Transactional 
public class ArticleServiceTest { 

    @Autowired(required = true) 
    private ArticleService articleService; 

    //private EmbeddedDatabase db; 

    @Before 
    public void setUp() { 
     //EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); 
     //db = builder.setType(EmbeddedDatabaseType.HSQL).setName("blog").addScript("classpath:create-db.sql").addScript("classpath:test-data.sql").build(); 
     //articleService.getArticleDao().setDataSource(db); 
     //articleService = new ArticleService(); 
    } 

    @After 
    public void tearDown() { 
     //articleService.getArticleDao().setDataSource(null); 
     //db.shutdown(); 
     //articleService = null; 
    } 

    @Test 
    public void test() 
    { 
     ArrayList<Article> articles = articleService.getFiveLastArticles(); 

     int number = articles.size(); 
     assertEquals(3, number); 
    } 

} 

ArticleService

package dk.martinrohwedder.blog.service; 

import dk.martinrohwedder.blog.domain.Article; 
import dk.martinrohwedder.blog.repository.ArticleDao; 
import java.util.ArrayList; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
/** 
* 
* @author Martin Rohwedder 
* @since 22-11-2012 
* @version 1.0 
*/ 
@Service("articleService") 
public class ArticleService { 

    @Autowired(required = true) 
    private ArticleDao articleDao; 

    public ArticleDao getArticleDao() { 
     return articleDao; 
    } 

    public void setArticleDao(ArticleDao articleDao) { 
     this.articleDao = articleDao; 
    } 

    public ArrayList<Article> getFiveLastArticles() 
    { 
     ArrayList<Article> articles = (ArrayList) articleDao.selectAllArticles(); 

     if (articles.size() > 5) { 
      articles = (ArrayList) articles.subList(articles.size() - 6, articles.size()); 
     } 

     return articles; 
    } 

} 

ArticleDao

package dk.martinrohwedder.blog.repository; 

import dk.martinrohwedder.blog.domain.Article; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.util.List; 
import javax.sql.DataSource; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.jdbc.core.JdbcTemplate; 
import org.springframework.jdbc.core.RowMapper; 
import org.springframework.stereotype.Repository; 
/** 
* 
* @author Martin Rohwedder 
* @since 22-11-2012 
* @version 1.0 
*/ 
@Repository 
public class ArticleDao implements IArticleDao { 

    private JdbcTemplate jdbcTemplate; 

    @Autowired(required = true) 
    public void setDataSource(DataSource dataSource) { 
     this.jdbcTemplate = new JdbcTemplate(dataSource); 
    } 

    @Override 
    public List<Article> selectAllArticles() { 
     String sql = "select article_id, headline from article"; 
     return this.jdbcTemplate.query(sql, new ArticleMapper()); 
    } 

    @Override 
    public Article selectArticle(int articleId) { 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 

    @Override 
    public void insertArticle(Article article) { 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 

    @Override 
    public void updateArticle(Article article) { 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 

    @Override 
    public void deleteArticle(int articleId) { 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 

    /** 
    * Article Mapper is responsible for map all rows found in a sql 
    * statement to Article objects. 
    */ 
    private static final class ArticleMapper implements RowMapper<Article> { 

     @Override 
     public Article mapRow(ResultSet rs, int rowNum) throws SQLException { 
      Article article = new Article(); 
      article.setId(rs.getInt("article_id")); 
      article.setHeadline(rs.getString("headline")); 

      return article; 
     } 

    } 

} 

測試的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:mvc="http://www.springframework.org/schema/mvc" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
     xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd"> 

    <context:component-scan base-package="dk.martinrohwedder.blog" /> 

    <mvc:annotation-driven /> 

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> 
     <property name="prefix" value="/views/" /> 
     <property name="suffix" value=".jsp" /> 
    </bean> 

    <bean id="embeddedDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="org.hsqldb.jdbc.JDBCDriver"/> 
     <property name="url" value="jdbc:hsqldb:mem:blog"/> 
     <property name="username" value="sa"/> 
     <property name="password" value=""/> 
    </bean> 

    <jdbc:embedded-database id="dataSource" type="HSQL"/> 
     <jdbc:initialize-database data-source="embeddedDataSource"> 
     <jdbc:script location="classpath:create-db.sql"/> 
     <jdbc:script location="classpath:test-data.sql"/> 
    </jdbc:initialize-database> 

</beans> 

創建-db.sql

create database if not exists blog; 

use blog; 

drop table if exists article; 

create table article 
(
    article_id int unsigned not null auto_increment, 
    headline varchar(30) not null, 
    primary key (article_id) 
); 

測試data.xml中

insert into article (article_headline) 
values ("Artikel 1"); 
insert into article (article_headline) 
values ("Artikel 2"); 
insert into article (article_headline) 
values ("Artikel 3"); 

因爲它們位於名爲Other Sources(src/main/resources)的包中,所以test-context.xml,create-db.sql和test-data.sql都位於類路徑中。

希望任何人都可以幫助我。

回答

3

嘗試在你的測試context.xml文件使用的
<context:annotation-config/>
代替
<mvc:annotation-driven />

<mvc:annotation-driven/>是Spring 3.0添加了標籤,其執行以下操作:

  1. 配置彈簧3類型ConversionService(替代 屬性編輯)
  2. 添加用於與@NumberFormat格式化數字字段支持
  3. 如果Joda時間位於類路徑中,則添加對使用@DateTimeFormat格式化日期,日曆和Joda時間字段的支持
  4. 添加對使用@Valid,i驗證@Controller輸入的支持如果JAXB位於類路徑上(使用@ RequestBody/@ ResponseBody轉換HTTP消息),則添加對讀寫XML支持的支持
  5. 添加對讀取和寫入JSON的支持,如果傑克遜是在類路徑(沿着相同的路線爲#5)

<context:annotation-config/>
看起來對在同一應用程序上下文豆註解它被定義,並聲明像@Autowired所有的一般註釋的支持,@ Resource,@Required,@PostConstruct等等。

+0

好吧,我會嘗試當我回家時,我在一個朋友家atm。 :) – Rohwedder

+0

嗨,似乎我的上下文文件是在錯誤的'classpath'他們必須在測試類路徑。我通過將一個名爲resources的文件夾添加到src/test /文件夾來解決此問題。在這裏我可以把我的應用程序上下文。我也從測試中刪除了@TestExecutionListeners。我還需要爲javax/servlet/serlvetException等的我的pom文件添加一些依賴關係。如果任何人有興趣,我的代碼可以在[Github](https://github.com/martin-rohwedder/MROBlog/tree/issue9)的分支issue9下看到。並且它也與註釋配置標籤一起工作。 – Rohwedder

1

它看起來像我articleDao沒有被設置。如果你想在測試中使用Spring bean,那麼你不能在你的測試中實例化服務。拿出這條線......

articleService = new ArticleService(); 
+0

我現在將其刪除...對不起,這是因爲我昨天嘗試了很多,然後我忘了取消註釋。我仍然得到了同樣的錯誤,雖然:( – Rohwedder

+0

啊,我雖然這太簡單了,是真的!你看了日誌嗎?大概是春天無法創建DAO,如果它爲空。 – Zutty

+0

在日誌中記錄?我是使用NetBeans作爲IDE – Rohwedder