单元测试ReflectionTestUtils指南
最后修改:2020年6月12日
1.介绍
ReflectionTestUtils是Spring Test Context框架的一部分。它是单元中使用的基于反射的实用程序方法的集合,以及用于设置非公共字段、调用非公共方法和注入依赖项的集成测试场景。
在本教程中,我们将看看如何使用ReflectionTestUtils在单元测试中通过几个例子。
2.Maven的依赖关系
让我们从将示例所需的所有必要依赖项的最新版本添加到pom.xml:
<依赖> < groupId > org。springframework < / groupId > < artifactId > spring上下文< / artifactId > <版本> 5.1.2中。RELEASE org。springframework < / groupId > < artifactId > spring测试< / artifactId > <版本> 5.1.2中。版本< / > < >范围测试范围< / > < / >的依赖
最新的spring上下文,spring测试依赖项可以从Maven Central存储库下载。
3.使用ReflectionTestUtils设置非公共字段的值
假设我们需要在单元测试中使用一个类的实例,这个类有一个私有字段,但没有公共setter方法。
让我们从创建它开始:
public class Employee {private Integer id;私人字符串名称;//标准的getter /setters}
通常我们不能访问私有字段id为测试赋值,因为没有公共setter方法。
我们可以使用ReflectionTestUtils.setField方法将值赋给私有成员id:
@Test public void whenNonPublicField_thenReflectionTestUtilsSetField(){雇员雇员=新雇员();ReflectionTestUtils.setField(employee, "id", 1); assertTrue(employee.getId().equals(1)); }
4.使用ReflectionTestUtils调用非公共方法
现在假设我们有一个私有方法employeeToString在员工类:
private String employeeToString(){return "id: " + getId() + ";+ getName();}
我们可以写一个单元测试employeeToString方法,即使它没有从外部访问员工类:
@Test public void whenNonPublicMethod_thenReflectionTestUtilsInvokeMethod(){雇员雇员=新雇员();ReflectionTestUtils.setField(employee, "id", 1); employee.setName("Smith, John"); assertTrue(ReflectionTestUtils.invokeMethod(employee, "employeeToString") .equals("id: 1; name: Smith, John")); }
5.使用ReflectionTestUtils注入依赖关系
让我们假设想要为下面的Spring组件编写一个单元测试,该组件有一个私有字段@ autowired注释:
@Component public class EmployeeService {@Autowired private HRService HRService;public String findEmployeeStatus(Integer employeeId) {return "Employee " + employeeId + " status: " + hrService.getEmployeeStatus(employeeId);}}
我们现在可以实现HRService组件如下:
@Component public class HRService {public String getEmployeeStatus(Integer employeeId) {return "Inactive";}}
控件的模拟实现HRService类通过使用5。我们将把这个mock注入EmployeeService实例,我们将在单元测试中使用它:
HRService HRService = mock(HRService.class);当(hrService.getEmployeeStatus (employee.getId ())) .thenReturn(“活跃”);
因为hrService是没有公共setter的私有字段吗ReflectionTestUtils.setField方法将我们上面创建的mock注入到这个私有字段。
EmployeeService EmployeeService = new EmployeeService();ReflectionTestUtils.setField(employeeService, "hrService", hrService);
最后,我们的单元测试如下所示:
@Test public void whenInjectingMockOfDependency_thenReflectionTestUtilsSetField(){雇员雇员=新雇员();ReflectionTestUtils.setField(employee, "id", 1); employee.setName("Smith, John"); HRService hrService = mock(HRService.class); when(hrService.getEmployeeStatus(employee.getId())).thenReturn("Active"); EmployeeService employeeService = new EmployeeService(); // Inject mock into the private field ReflectionTestUtils.setField(employeeService, "hrService", hrService); assertEquals( "Employee " + employee.getId() + " status: Active", employeeService.findEmployeeStatus(employee.getId())); }
我们应该注意,对于在bean类中使用字段注入这一事实,这种技术是一种变通方法。如果我们换成构造函数注入那么这种方法就没有必要了。
6.结论
在本教程中,我们展示了如何使用ReflectionTestUtils在单元测试中通过几个例子。
和往常一样,可以找到代码示例在Github。