簡體   English   中英

SpringBoot:ReflectionTestUtils.setFields 是如何工作的?

[英]SpringBoot : How ReflectionTestUtils.setFields work?

考慮下面的代碼:

服務

class MyService{

  @Autowired
  private ModelMapper modelMapper;


  void validate(){

       ResponseObject obj = modelMapper.map( REQUEST, ResponseObject.class);
 
       // In testing, if I am not mocking this Model Mapper, an exception will be thrown.

  }

}

測試

在 JUnit 測試用例中,我使用的是ReflectionTestUtils.setField("", "", "")而不是 mocking,並且映射按預期進行。 但我不知道發生了什么以及它是如何工作的。 我參考了許多來源,但我找不到任何可靠的資源。 誰能告訴我 ReflectionTestUtils 是什么,它是如何工作的,以及何時使用它?

@InjectMocks
MyService service;

private ModelMapper modelMapper;

@BeforeEach
void setup() {
    modelMapper = new ModelMapper();
    ReflectionTestUtils.setField( service, "modelMapper", modelMapper);

}

而不是做非常反模式(如果你問我):

@Autowired
private ModelMapper modelMapper;

你總是可以通過構造函數注入它:

private final ModelMapper modelMapper;

class MyService(ModelMapper modelMapper) {
    this.modelMapper = modelMapper;
}

MyService是 spring 知道的 bean 時,自動裝配將為您發生。 所以不需要使用ReflectionTestUtils.setField 這將在jdk-17及更高版本中開始失敗。


由於您現在通過構造函數傳遞它,因此使用模擬注入是微不足道的。

它在封面下使用反射 API 來設置 object 字段的值。

關於何時使用它, 文檔已經提供了一些信息:

您可以在需要更改常量值、設置非公共字段、調用非公共 setter 方法或在測試應用程序代碼時調用非公共配置或生命周期回調方法的測試場景中使用這些方法。用例如下:

  • ORM 框架(例如 JPA 和 Hibernate)允許私有或受保護的字段訪問,而不是域實體中屬性的公共設置方法。

  • Spring 對注解(如@Autowired、@Inject 和@Resource)的支持,為私有或受保護字段、setter 方法和配置方法提供依賴注入。

  • 對生命周期回調方法使用 @PostConstruct 和 @PreDestroy 等注解。

我通常用它來設置一些虛擬域對象,這些對象是 JPA 實體進行測試。 由於它們的 ID 由 Hibernate 管理並具有良好的封裝性,因此它們沒有任何 setter 或構造函數來配置其 ID 值,因此需要使用它來為其 ID 設置一些虛擬值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM