我正在为一个服务类编写单元测试,我们称之为
MyService
,其格式如下:
public class MyService {
private final HttpHeaders headers = new HttpHeaders();
public MyService(MyRepository myRepository) {
headers.setBasicAuth(myRepository.getValue("login"), myRepository.getValue("password"));
}
// OTHER PARTS OF THE CODE
}
在
MyService
类的构造函数中,我将值设置为 headers
字段。在编写单元测试时,我面临以下问题:
@ContextConfiguration(classes = MyService.class)
class MyServiceTest {
@Autowired
private MyService myService;
@BeforeEach
void init() {
mockValue("login", "login_value");
mockValue("password", "password_value");
}
// OTHER PARTS OF THE CODE
}
我有一个方法
mockValue
可以适当地模拟这些值。问题是:
MyService
的构造函数在init()
的MyServiceTest
方法之前工作。结果, myRepository.getValue("login")
返回 null 并且 headers.setBasicAuth()
方法抛出异常:“用户名不能为 null”。
如何处理?如何在 MyService 的构造函数运行之前模拟值?
我尝试创建另一个类,在其中我可以模拟值并将其注入到我的测试类中。它没有像我预期的那样工作。
您可以使用 ReflectionTestUtils
@Service
public class MyService {
private final HttpHeaders headers = new HttpHeaders();
public MyService(MyRepository myRepository) {
headers.setBasicAuth(myRepository.getValue("login"), myRepository.getValue("password"));
}
public String getHeader(String key){
return headers.getFirst(key);
}
}
@SpringBootTest
class MyServiceTest {
@Autowired
private MyService myService;
@BeforeEach
void init() {
mockValue("mocked_login_value", "mocked_password_value");
}
private void mockValue(String login_value, String password_value) {
final HttpHeaders value = new HttpHeaders();
value.setBasicAuth(login_value, password_value);
ReflectionTestUtils.setField(myService, "headers", value);
}
@Test
void invokeService() {
//bW9ja2VkX2xvZ2luX3ZhbHVlOm1vY2tlZF9wYXNzd29yZF92YWx1ZQ==" is equal to mocked_login_value:mocked_password_value
Assertions.assertEquals("bW9ja2VkX2xvZ2luX3ZhbHVlOm1vY2tlZF9wYXNzd29yZF92YWx1ZQ==", myService.getHeader("authorization"));
}
}
我在本地测试过,有效。不优雅,但由于您无法更改 MyService,因此这可能是最容易做到的。