2017-10-14 135 views
1

我對Spring控制器的單元測試概念很陌生。我正在追蹤我在網上找到的一些例子,並試圖實施他們的測試策略。這是我的基本控制器:如何使用註釋單元測試Spring Controller?

@Controller 
public class GreetingController { 

    @RequestMapping("/greeting") 
    public String greeting(@RequestParam(value = "name2", required = false, defaultValue = "World2") String name2, 
          Model model) { 

     model.addAttribute("name", name2); 
     return "greeting"; 
    } 

} 

這是我的單元測試:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration 
@WebAppConfiguration 
public class ControllerGreetingTest { 

    private MockMvc mockMvc; 

    @Autowired 
    GreetingController greetingController; 
    @Test 
    public void shouldReturnSomething() throws Exception { 
     mockMvc.perform(get("/greeting")) 
       .andExpect(status().isOk()) 
       .andExpect(view().name("greeting")); 
    } 

} 

似乎很簡單的,但我得到了以下錯誤:

java.lang.IllegalStateException: Neither GenericXmlWebContextLoader nor AnnotationConfigWebContextLoader was able to detect defaults, and no ApplicationContextInitializers were declared for context configuration [[email protected] declaringClass = 'com.practice.demo.ControllerGreetingTest', locations = '{}', classes = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader']

我假設我有向@ContextConfiguration註釋添加參數,但不確定要包含哪些參數。

EDIT =這是我到目前爲止有:

public class ControllerGreetingTest { 

    private MockMvc mockMvc; 

    @Before 
    public void setup(){ 
     this.mockMvc = standaloneSetup(new GreetingController()).build(); 
    } 

    @Test 
    public void shouldReturnDefaultString() throws Exception { 
     mockMvc.perform(get("/greeting")) 
       .andExpect(status().isOk()) 
       .andExpect(view().name("greetings")) 
       .andExpect(model().attribute("name","World2")); 
    } 

} 

它的工作,但它不使用任何Spring註解像我這樣做之前..這種做法並不好,所以試圖找出爲什麼當我在我的測試文件中包含註釋時,我總是收到錯誤。

我POM:

<dependencies> 
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-test</artifactId> 
     <version>1.5.7.RELEASE</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-data-mongodb</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-thymeleaf</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-devtools</artifactId> 
     <optional>true</optional> 
    </dependency> 
    <dependency> 
     <groupId>org.hamcrest</groupId> 
     <artifactId>hamcrest-all</artifactId> 
     <version>1.3</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <scope>test</scope> 
     <exclusions> 
      <exclusion> 
       <artifactId>hamcrest-core</artifactId> 
       <groupId>org.hamcrest</groupId> 
      </exclusion> 
     </exclusions> 
    </dependency> 
    <dependency> 
     <groupId>org.mockito</groupId> 
     <artifactId>mockito-core</artifactId> 
     <version>1.9.5</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-test</artifactId> 
     <version>3.2.3.RELEASE</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <scope>test</scope> 
    </dependency> 
    <!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver --> 
     <dependency> 
      <groupId>org.mongodb</groupId> 
      <artifactId>mongo-java-driver</artifactId> 
      <version>3.4.2</version> 
     </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-dependencies</artifactId> 
     <version>1.5.7.RELEASE</version> 
     <scope>test</scope> 
    </dependency> 

</dependencies> 
+0

嘗試使用@RunWith(SpringRunner.class)如果我們正在談論春季啓動 – Antoniossss

+0

@Antoniossss我正在使用Spring啓動。我在包含SpringLunner.class的時候包含了什麼依賴性,因爲我得到了'無法解析符號'SpringRuner' – dfqupwndguerrillamailde

+0

org.springframework.boot:spring-boot-starter-test – Antoniossss

回答

2

對於項目org.springframework.boot:spring-boot-starter-test可以使用

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = App.class) 
public class ControllerGreetingTest { 
    ... 
} 

哪裏App.class是你@SpringBootApplication註解的主應用程序類。但你最好閱讀documentation。如果你不希望包括(classes = App.class)一部分,您還可以更改folder structure

對於簡單的控制器就可以進行簡單的獨立測試

@RunWith(SpringRunner.class) 
@WebMvcTest(controllers = ControllerGreeting.class) 
public class ControllerGreetingTest { 
    @Autowired 
    private MockMvc mockMvc; 

    ... 

} 
1

您應該使用spring-boot-starter-test依賴。它有幾乎所有的測試。

並且爲了測試彈簧應用程序的控制器部分,您應該爲您的測試類使用@WebMvcTest註釋。有了這個註釋,spring將只爲控制器部分加載上下文。另外,如果使用此註釋,則不需要設置方法。你可以簡單地自動裝載mockMvc。您的測試類應該是這樣的:

@RunWith(SpringRunner.class) 
@WebMvcTest(GreetingController.class) 
public class ControllerGreetingTest { 

    @Autowired 
    private MockMvc mockMvc; 

    @MockBean 
    private SomeServiceClass someServiceClass; 

    @Test 
    public void shouldReturnDefaultString() throws Exception { 
     mockMvc.perform(get("/greeting")) 
      .andExpect(status().isOk()) 
      .andExpect(view().name("greetings")) 
      .andExpect(model().attribute("name","World2")); 
    } 

} 

注:您的控制器沒有任何自動裝配領域。如果控制器有一些自動裝配的對象,如服務或存儲庫對象。你可以簡單地嘲笑他們註釋@MockBean,你可以看到上面的代碼。

其他測試片註釋見this link彈簧提供

0

只需添加@ContextConfiguration註釋和參考的一個或多個XML配置文件位置或一個或多個配置類。否則Spring不能自動連接你的控制器,應該測試它。

例:你想測試一控制器,該控制器通過使用@Autowired爲MyService:

MyControllerTest:噴射控制器,它應該使用所述MyTestConfig配置類進行測試。

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {MyTestConfig.class}) 
@WebAppConfiguration 
public class MyControllerTest { 

    private MockMvc mockMvc; 

    @Autowired 
    private MyController controller; 

    @Before 
    public void setUp() { 
    mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); 
    } 

    // Tests 
} 

MyTestConfig:返回所有豆子,這些都要求進行測試。使用Mockito來模擬控制器的依賴性,因爲我們只想測試控制器而不是服務層。

@Configuration 
public class MyTestConfig { 

    @Bean 
    public MyService myService() { 
    return Mockito.mock(MyService.class); 
    } 

    @Bean 
    public MyController myController() { 
    return new MyController(); 
    } 
} 
相關問題