Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Junit测试中使用ReflectionTestUtils.setField()_Java_Spring_Junit - Fatal编程技术网

Java 在Junit测试中使用ReflectionTestUtils.setField()

Java 在Junit测试中使用ReflectionTestUtils.setField(),java,spring,junit,Java,Spring,Junit,我是新手,所以我有个问题。有人能告诉我为什么我们在Junit测试中使用ReflectionTestUtils.setField()。如评论中所述,java文档非常好地解释了用法。但我想给你们一个简单的例子 假设您有一个具有私有或受保护字段访问权限的实体类,并且没有提供setter方法 @Entity public class MyEntity { @Id private Long id; public Long getId(Long id){ this.id

我是新手,所以我有个问题。有人能告诉我为什么我们在Junit测试中使用
ReflectionTestUtils.setField()

如评论中所述,java文档非常好地解释了用法。但我想给你们一个简单的例子

假设您有一个具有私有或受保护字段访问权限的实体类,并且没有提供setter方法

@Entity
public class MyEntity {

   @Id
   private Long id;

   public Long getId(Long id){
       this.id = id;
   }
}
在测试类中,由于缺少setter方法,您无法设置
实体的
id

使用
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

但是,尝试一下并阅读。

当我们想要编写单元测试时,它非常有用,例如:

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);
   } 
}
还有一个用例:

我们在应用程序属性中外部化了许多属性,如:URL、端点和许多其他属性,如下所示:

kf.get.profile.endpoint=/profile
kf.get.clients.endpoint=clients
  @Value("${kf.get.clients.endpoint}")
  private String getClientEndpoint
ReflectionTestUtils.setField(targetObject,"getClientEndpoint","lorem");
然后在应用程序中使用它,如下所示:

kf.get.profile.endpoint=/profile
kf.get.clients.endpoint=clients
  @Value("${kf.get.clients.endpoint}")
  private String getClientEndpoint
ReflectionTestUtils.setField(targetObject,"getClientEndpoint","lorem");
每当我们编写单元测试时,我们都会得到NullPointerException,因为Spring不能像@Autowired那样注入@value。(至少在目前,我不知道其他选择。)为了避免这种情况,我们可以使用ReflectionTestUtils来注入外部化属性。如下图所示:

kf.get.profile.endpoint=/profile
kf.get.clients.endpoint=clients
  @Value("${kf.get.clients.endpoint}")
  private String getClientEndpoint
ReflectionTestUtils.setField(targetObject,"getClientEndpoint","lorem");

感谢您进行上述讨论,下面的部分还可以通过阅读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);
    }
}
import org.junit.Before;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入org.springframework.beans.factory.annotation.Value;
导入org.springframework.test.context.ContextConfiguration;
导入org.springframework.test.context.TestPropertySource;
导入org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
导入org.springframework.test.util.ReflectionTestUtils;
导入java.util.List;
导入静态org.junit.jupiter.api.Assertions.*;
@RunWith(SpringJUnit4ClassRunner.class)
@上下文配置
@TestPropertySource(“类路径:application test.properties”)
公共类FileRetrievalServiceTest{
@值(${fs.local.quantial.directory}”)
私有字符串localQuarantineDirectory;
@值(${fs.local.quantial.error.directory}”)
私有字符串LocalQuarantineErrorDirectory;
@值(${fs.local.quantial.tmp.directory}”)
私有字符串localquantinetmpdirectory;
@值(${fs.local.keys.file}”)
私有字符串localKeyFile;
私有文件检索服务文件检索服务;
@以前
public void setUp()引发异常{
FileRetrievalService=newFileRetrievalServiceImpl();
ReflectionTestUtils.setField(fileretrievalservice,“keyFile”,localKeyFile);
}
@试验
public void应检索IstofficesinQuarantineDirectory(){
//给定
ReflectionTestUtils.setField(FileRetrievalService,“quarantineDirectory”,localQuarantineDirectory);
//什么时候
List quarantineFiles=FileRetrievalService.RetrievelistOfficesinQuarantineDirectory();
//然后
assertNotNull(隔离文件);
assertEquals(quarantineFiles.size(),4);
}
}

请告诉我您想要实现什么以及您尝试了什么?很好地解释了用法。我看到了一些junit类的示例,在这些示例中,在Before annotation中使用了reflectiontestUtils.setField(),但我无法理解为什么要使用它以及需要它做什么。我只想知道一些基本知识@Mritunjay不看那个例子,我只能猜测,这不是我会尝试的。你们不需要以不自然的方式改变测试中的系统。在单元测试中使用反射与单元测试的想法相反。如果我们使用一个类对象(partyServiceImpl),比如ReflectionTestUtils.setField(accountServiceImpl,“partyServiceImpl”,partyServiceImpl),我还有一个问题;是否每次都需要模拟partyServiceImpl对象@Patrick@rohitsharma这取决于您的用例。现在,您只需将partyServiceImpl对象设置为accountServiceImpl对象。如果只需要在测试对象中保存值,则不需要额外的模拟