2015-12-23 12 views
14

I持って、次のクラス:SpringbootユニットテストAutowired

ApplicationAndConfigurationクラス

package mypackage.service; 

import mypackage.service.util.MyUtility; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.annotation.Bean; 

@SpringBootApplication 
public class ApplicationAndConfiguration { 


    public static void main(String[] args) { 
     ApplicationContext context = SpringApplication.run(ApplicationAndConfiguration.class, new String[]{}); 
    } 

    @Bean(initMethod="init") 
    public MyUtility birtUtil() { 
     return new MyUtility(); 
    } 
} 

MyRestControllerクラス

package mypackage.service.controllers; 

import mypackage.service.util.MyUtility; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.RestController; 

@RestController 
public class MyRestController { 

    @Autowired 
    private MyUtility util; 

    @RequestMapping("/getLibraryName") 
    public String getMessageFromRest(@RequestParam String name) { 

     return "name was " + name + "//" + util.getMessage(); 
    } 
} 

MyUtility社クラス

アプリケーションを起動して独立したjarファイルとして実行したり、IDE(Eclipse)から実行しても、まったく問題はありません。すべて正常に動作します。

はしかし、私は私のMyRestControllerクラスをテストするためのユニットテストを書きたい...とAutowiredフィールドutilのがヌルであるので、私は(MyRestControllerクラス内)NPEを取得しています。任意のポインタなぜ...だけではなく、標準的なアプリケーションの実行中に、私のAutowiredフィールドがテスト中に満たされますように、私は間違いなく何かが欠けている

package mypackage.service.controllers; 

import static org.hamcrest.Matchers.equalTo; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 
import mypackage.service.ApplicationAndConfiguration; 

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.boot.test.SpringApplicationConfiguration; 
import org.springframework.http.MediaType; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.web.WebAppConfiguration; 
import org.springframework.test.web.servlet.MockMvc; 
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 
import org.springframework.test.web.servlet.setup.MockMvcBuilders; 

@SpringApplicationConfiguration(classes = ApplicationAndConfiguration.class) 
@WebAppConfiguration 
@RunWith(SpringJUnit4ClassRunner.class) 
public class TestController { 

    private MockMvc mvc; 

    @Before 
    public void setup() throws Exception { 
     mvc = MockMvcBuilders.standaloneSetup(new MyRestController()).build(); 
    } 

    @Test 
    public void MyTestController() throws Exception { 

     mvc.perform(MockMvcRequestBuilders.get("/getLibraryName").param("name", "test").accept(MediaType.APPLICATION_JSON)) 
     .andExpect(status().isOk()) 
     .andExpect(content().string(equalTo("name was test//MyUtility correctly initialized!"))); 
    } 
} 

:ここ

は私のテストクラスですそれは動作しません?

+0

フィールド注入の代わりにコンストラクタ注入を使用すると、このような問題を特定するのに役立ち、分離された単体テストをはるかに簡単にすることができます。 – chrylis

答えて

6

MockMvcスタンドアロン設定は単体テスト用です。テストでSpringコンテキストを作成する際に、統合テストを行っています。これらの2種類のテストを混在させないでください。

だから、それをこのように変更します。

@SpringApplicationConfiguration(classes = ApplicationAndConfiguration.class) 
@WebAppConfiguration 
@RunWith(SpringJUnit4ClassRunner.class) 
public class TestController { 

    private MockMvc mvc; 

    @Autowired 
    private WebApplicationContext webApplicationContext; 

    @Before 
    public void setup() throws Exception { 
     mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); 
    } 
18

SpringBoot 1.4以来、すべてのクラスが変更され、https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4.0-M2-Release-Notesを非推奨しました。ランナーと構成を以下のものに交換してください。 SpringRunnerはあなたのためのテストフレームワークを検出します。

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = { FileService.class, AppProperties.class, DownloadConfigEventHandler.class }) 
@EnableConfigurationProperties 
public class ConfigMatrixDownloadAndProcessingIntegrationTests extends ConfigMatrixDownloadAbstractTest { 

    // @Service FileService 
    @Autowired 
    private FileService fileService; 

    // @Configuration AppProperties 
    @Autowired 
    private AppProperties properties; 

    // @Compoenet DownloadConfigEventHandler 
    @Autowired 
    private DownloadConfigEventHandler downloadConfigEventHandler;  
    .. 
    .. 
} 

これらのすべてのインスタンスは、期待どおりに自動応答されます。パブリッシャーのSpringイベントでも、https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2のように正常に動作しています。

+0

統合テストケーススーツまたはdevテストのためにうまく動作します – Hrishikesh

+0

テストにサービスインスタンスをオートワイヤーするのに役立ちます。 –