簡體   English   中英

在 Junit 測試中使用 ReflectionTestUtils.setField()

[英]Use of ReflectionTestUtils.setField() in Junit testing

我是 JUnittesting 的新手,所以我有一個問題。 誰能告訴我為什么我們在 Junit 測試中使用ReflectionTestUtils.setField()示例。

正如評論中提到的,java 文檔很好地解釋了用法。 但我也想給你舉一個簡單的例子。

假設您有一個具有私有或受保護字段訪問權限的 Entity 類,並且沒有提供 setter 方法

@Entity
public class MyEntity {

   @Id
   private Long id;

   public Long getId(Long id){
       this.id = id;
   }
}

在您的測試類中,由於缺少 setter 方法,您無法設置entityid

使用ReflectionTestUtils.setField您可以出於測試目的執行此操作:

ReflectionTestUtils.setField(myEntity, "id", 1);

參數描述:

public static void setField(Object targetObject,
                            String name,
                            Object value)
Set the field with the given name on the provided targetObject to the supplied value.
This method delegates to setField(Object, String, Object, Class), supplying null for the type argument.

Parameters:
targetObject - the target object on which to set the field; never null
name - the name of the field to set; never null
value - the value to set

但試一試並閱讀文檔

另一個用例:

我們外部化了許多屬性,例如:URL、端點和應用程序屬性中的許多其他屬性,如下所示:

kf.get.profile.endpoint=/profile
kf.get.clients.endpoint=clients

然后在應用程序中使用它,如下所示:

  @Value("${kf.get.clients.endpoint}")
  private String getClientEndpoint

每當我們編寫 unit test 時,我們都會得到NullPointerException ,因為 Spring 不能像 @Autowired 那樣注入 @value 。 (至少目前,我不知道替代方案。)所以為了避免我們可以使用ReflectionTestUtils來注入外部屬性。 如下所示:

ReflectionTestUtils.setField(targetObject,"getClientEndpoint","lorem");

當我們要編寫單元測試時,它非常有用,例如:

class A{
   int getValue();
}

class B{
   A a;
   int caculate(){
       ...
       int v = a.getValue();
       ....
   }
}

class ServiceTest{
   @Test
   public void caculateTest(){
       B serviceB = new B();
       A serviceA = Mockito.mock(A.class);
       Mockito.when(serviceA.getValue()).thenReturn(5);
       ReflectionTestUtils.setField(serviceB, "a", serviceA);
   } 
}

感謝您的上述討論,以下部分還可以通過讀取 application-test.properties 中的屬性來編寫單元測試。

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.util.ReflectionTestUtils;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@TestPropertySource("classpath:application-test.properties")
public class FileRetrivalServiceTest {

@Value ("${fs.local.quarantine.directory}")
private String localQuarantineDirectory;

@Value ("${fs.local.quarantine.wrong.directory}")
private String localQuarantineWrongDirectory;

@Value ("${fs.local.quarantine.tmp.directory}")
private String localQuarantineTmpDirectory;

@Value ("${fs.local.keys.file}")
private String localKeyFile;
private FileRetrivalService fileRetrivalService;

@Before
public void setUp() throws Exception {
    fileRetrivalService = new FileRetrivalServiceImpl();
    ReflectionTestUtils.setField(fileRetrivalService, "keyFile", localKeyFile);
}

@Test
public void shouldRetrieveListOfFilesInQuarantineDirectory() {
    // given
    ReflectionTestUtils.setField(fileRetrivalService, "quarantineDirectory", localQuarantineDirectory);

    // when
    List<IcrFileModel> quarantineFiles = fileRetrivalService.retrieveListOfFilesInQuarantineDirectory();

    // then
    assertNotNull(quarantineFiles);
    assertEquals(quarantineFiles.size(), 4);
    }
}

ReflectionTestUtils.setField 用於各種上下文。 但最常見的情況是當你有一個 class 並且里面有私有訪問的屬性,所以你想對這個 class 做測試文件。

因此,可能的解決方案是 ReflectionTestUtils 下面的下一個示例如何:

public class BBVAFileProviderTest {

@Mock
private BBVAFileProvider bbvaFileProvider;

@Before
public void setup() throws Exception {

    bbvaFileProvider = new BBVAFileProvider(payoutFileService, bbvaFileAdapter, bbvaCryptographyService, amazonS3Client, providerRequestService, payoutConfirmationService);
    ReflectionTestUtils.setField(this.bbvaFileProvider, "bbvaClient", this.bbvaClient);
}

在這些示例中,您可以看到使用 ReflectionTestUtils.setField 將值設置為私有字段,因為它沒有 setter 方法。

暫無
暫無

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

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