Spring Boot中文參考指南(2.1.6) 46.3.6、使用 JMX

下一篇[未完待續]

Spring Boot中文參考指南(2.1.6) 46.3.6、使用 JMX

<code>英文原文:https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-testing.html/<code>
<code>GitHub:https://github.com/jijicai/Spring/tree/master/spring-boot/<code>

46.3.6、使用 JMX

由於測試上下文框架緩存上下文,因此默認情況下禁用 JMX 以防止相同的組件在同一域上註冊。如果此類測試需要訪問 MBeanServer,請考慮將其標記為髒(dirty):

Spring Boot中文參考指南(2.1.6) 46.3.6、使用 JMX

<code>@RunWith(SpringRunner.class)
@SpringBootTest(properties = "spring.jmx.enabled=true")
@DirtiesContext
public class SampleJmxTests {

@Autowired
private MBeanServer mBeanServer;

@Test
public void exampleTest() {
// ...
}

}
/<code>

46.3.7、模擬和監視 Beans

運行測試時,有時需要在應用程序上下文中模擬某些組件。例如,你可能在某個遠程服務上有一個 facade,在開發期間該服務不可用。當你希望模擬在實際環境中可能難以觸發的故障時,模擬也很有用。

Spring Boot 包含一個 @MockBean 註解,該註解可用於為應用上下文中的 bean 定義 Mockito 模擬。可以使用註解添加新 bean 或替換單個現有 bean 定義。註解可直接用於測試類、測試中的字段或 @Configuration 類和字段。在字段上使用時,也會注入創建的模擬的實例。mock bean 在每個測試方法後自動重置。

註釋:

如果你的測試使用 Spring Boot 的測試註解之一(如 @SpringBootTest),則會自動啟用此功能。要將此功能與其他安排一起使用,必須顯式添加監聽器,如下面示例所示:

<code>@TestExecutionListeners(MockitoTestExecutionListener.class)/<code>

以下示例使用模擬(mock)實現替換現有的 RemoteService bean:

Spring Boot中文參考指南(2.1.6) 46.3.6、使用 JMX

<code>import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.mock.mockito.*;
import org.springframework.test.context.junit4.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {

@MockBean
private RemoteService remoteService;

@Autowired
private Reverser reverser;

@Test
public void exampleTest() {
// RemoteService has been injected into the reverser bean
given(this.remoteService.someCall()).willReturn("mock");
String reverse = reverser.reverseSomeCall();
assertThat(reverse).isEqualTo("kcom");
}

}/<code>

註釋:@MockBean 不能用於模擬在應用程序上下文刷新期間執行的 bean 的行為。執行測試時,應用程序上下文刷新已完成,配置模擬行為為時已晚。在這種情況下,我們建議使用 @Bean 方法來創建和配置模擬。

另外,你可以使用 @SpyBean 將任何現有的 bean 與 Mockito spy 打包在一起。有關詳細信息,請參閱 Javadoc。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/api/org/springframework/boot/test/mock/mockito/SpyBean.html )

註釋:雖然 Spring 的測試框架在測試之間緩存應用程序上下文,併為共享相同配置的測試重用上下文,但 @MockBean 或 @SpyBean 的使用會影響緩存鍵, 這很可能會增加上下文的數量。

提示:如果你使用 @SpyBean 來監視帶有 @Cacheable 方法的 bean,該方法按名稱引用參數,則你的應用程序必須使用 -parameters 進行編譯。這確保參數名稱在 bean 被監視後可用於緩存基礎設施。

46.3.8、自動配置的測試

Spring Boot 的自動配置系統適用於應用程序,但有時對測試來說可能有點太多。這通常有助於只加載測試應用程序 “切片” 所需的配置部分。例如,你可能想要測試 Spring MVC 控制器是否正確映射 URLs,並且你不想在這些測試中涉及數據庫調用,或者你可能想要測試 JPA 實體, 當這些測試運行時,你對 web 層不感興趣。

spring-boot-test-autoconfigure 模塊包含許多註解,可用於自動配置此類 “切片”。它們中的每一個都以類似的方式工作,提供一個加載 ApplicationContext 的 @…Test 註解和一個或多個可用於自定義自動配置設置的 @AutoConfigure… 註解。

註釋:每個切片將組件掃描限制為適當的組件,並加載一組非常受限制的自動配置類。如果你需要排除其中一個,大多數 @…Test 註解都提供了一個 excludeAutoConfiguration 屬性。或者,你可以使用 @ImportAutoConfiguration#exclude。

註釋:不支持在一個測試中使用多個 @…Test 註解來包含多個 “切片”。如果你需要多個 “切片”,請選擇其中一個 @…Test 註解,並手動包含其他 “切片” 的 @AutoConfigure… 註解。

提示:也可以將 @AutoConfigure… 註解與標準的 @SpringBootTest 註解一起使用。如果你對應用程序的“切片”不感興趣,但需要一些自動配置的測試 bean,則可以使用此組合。

46.3.9、自動配置的 JSON 測試

要測試對象 JSON 序列化和反序列化是否按預期工作,可以使用 @JsonTest 註解。@JsonTest 自動配置可用的受支持 JSON 映射器,該映射器可以是以下庫之一:

(1)Jackson ObjectMapper、任何 @JsonComponent bean 和任何 Jackson Module

(2)Gson

(3)Jsonb

提示:可以在附錄中找到由 @JsonTest 啟用的自動配置的列表。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/test-auto-configuration.html)

如果需要配置自動配置的元素,可以使用 @AutoConfigureJsonTesters 註解。

Spring Boot 包括基於 AssertJ 的幫助器,它們與 JSONAssert 和 JsonPath 庫一起工作,檢查 JSON 是否如預期的那樣出現。JacksonTester、GsonTester、JsonbTester 和 BasicJsonTester 類可以分別用於 Jackson、Gson、Jsonb 和 String。使用 @JsonTest 時,測試類上的任何幫助器字段都可以 @Autowired。以下示例展示了 Jackson 的測試類:

Spring Boot中文參考指南(2.1.6) 46.3.6、使用 JMX

<code>import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.json.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.json.*;
import org.springframework.test.context.junit4.*;

import static org.assertj.core.api.Assertions.*;

@RunWith(SpringRunner.class)
@JsonTest
public class MyJsonTests {

@Autowired
private JacksonTester<vehicledetails> json;

@Test
public void testSerialize() throws Exception {
VehicleDetails details = new VehicleDetails("Honda", "Civic");
// Assert against a `.json` file in the same package as the test
assertThat(this.json.write(details)).isEqualToJson("expected.json");
// Or use JSON path based assertions
assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make")
.isEqualTo("Honda");
}

@Test
public void testDeserialize() throws Exception {
String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
assertThat(this.json.parse(content))
.isEqualTo(new VehicleDetails("Ford", "Focus"));
assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
}

}/<vehicledetails>/<code>

註釋:JSON 幫助器類也可以直接用於標準單元測試。為此,如果不使用 @JsonTest,請在 @Before 方法中調用幫助器的 initFields 方法。

如果你使用 Spring Boot 的基於 AssertJ 的幫助器在給定的 JSON 路徑上對數字值進行斷言,則可能無法根據類型使用 isEqualTo。相反,你可以使用 AssertJ 的 satisfies 來斷言值與給定條件匹配。例如,下面的示例斷言實際的數字是一個接近 0.15 的浮點值,偏移量為 0.01。

Spring Boot中文參考指南(2.1.6) 46.3.6、使用 JMX

<code>assertThat(json.write(message))
.extractingJsonPathNumberValue("@.test.numberValue")
.satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f)));/<code>

46.3.10、自動配置的 Spring MVC 測試

要測試 Spring MVC 控制器是否按預期工作,請使用 @WebMvcTest 註解。@WebMvcTest 自動配置 Spring MVC 基礎設施,並將掃描的 bean 限制為 @Controller、@ControllerAdvice、@JsonComponent、Converter、GenericConverter、Filter、WebMVCConfiguer 和 HandlerMethodArgumentResolver。使用此註解時,不掃描常規 @Component bean。

提示:可以在附錄中找到由 @WebMvcTest 啟用的自動配置設置的列表。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/test-auto-configuration.html )

提示:如果你需要註冊額外的組件,比如 Jackson Module,你可以在測試中使用 @Import 來導入額外的配置類。

通常,@WebMvcTest 僅限於單個控制器,並與 @MockBean 結合使用,為所需的協作者提供模擬實現。

@WebMvcTest 也會自動配置 MockMvc。Mock MVC 提供了一種強大的方法來快速測試 MVC 控制器,而不需要啟動完整的 HTTP 服務器。

提示:你還可以在非 @WebMvcTest(如 @SpringBootTest)中自動配置 MockMvc,方法是使用 @AutoConfigureMockMvc 對其進行註解。以下示例使用 MockMvc:

Spring Boot中文參考指南(2.1.6) 46.3.6、使用 JMX

<code>import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyControllerTests {

@Autowired
private MockMvc mvc;

@MockBean
private UserVehicleService userVehicleService;

@Test
public void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk()).andExpect(content().string("Honda Civic"));
}

}
/<code>

提示:如果你需要配置自動配置的元素(例如,當應用 servlet 過濾器時),你可以使用 @AutoConfigureMockMvc 註解中的屬性。

如果使用 HtmlUnit 或 Selenium,自動配置還提供了一個 HTMLUnit WebClient bean 和/或一個 WebDriver bean。以下示例使用 HtmlUnit:

Spring Boot中文參考指南(2.1.6) 46.3.6、使用 JMX

<code>import com.gargoylesoftware.htmlunit.*;
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyHtmlUnitTests {

@Autowired
private WebClient webClient;

@MockBean
private UserVehicleService userVehicleService;

@Test
public void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
}

}/<code>

註釋:默認情況下,Spring Boot 將 WebDriver bean 放在一個特殊的“scope”中,以確保驅動程序在每次測試後退出,並注入新實例。如果你不想要這種行為,你可以將 @Scope("singleton") 添加到你的 WebDriver @Bean 定義中。

警告:Spring Boot 創建的 webDriver 範圍將替換任何同名的用戶定義範圍。如果你定義自己的 webDriver 範圍,你可能會發現在使用 @WebMvcTest 時它停止工作。

如果類路徑上有Spring Security,@WebMvcTest 也將掃描 WebSecurityConfigurer bean。你可以使用 Spring Security 的測試支持,而不是完全禁用此類測試的安全性。有關如何使用 Spring Security 的 MockMvc 支持的更多詳細信息,請參見第 80 章:使用 Spring Security 進行測試的操作指南部分。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/howto-use-test-with-spring-security.html )

提示:有時編寫 Spring MVC 測試是不夠的;Spring Boot 可以幫助你在實際的服務器上運行完整的端到端測試。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-with-running-server )

下一篇[未完待續]


分享到:


相關文章: