在单元测试中,如何在注入服务类的构造函数工作之前模拟测试类中的值

问题描述 投票:0回答:1

我正在为一个服务类编写单元测试,我们称之为

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 的构造函数运行之前模拟值?

我尝试创建另一个类,在其中我可以模拟值并将其注入到我的测试类中。它没有像我预期的那样工作。

java spring junit mockito
1个回答
0
投票

您可以使用 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,因此这可能是最容易做到的。

© www.soinside.com 2019 - 2024. All rights reserved.