gpt4 book ai didi

java - @RefreshScope 似乎忽略了 Mockito 的模拟

转载 作者:行者123 更新时间:2023-12-01 10:14:29 25 4
gpt4 key购买 nike

我正在使用 Spring Boot 和 Spring Cloud Config 服务实现一个服务来提供配置值。在我的服务中,我有几个配置值,当远程 Git 存储库中的值发生更改时需要刷新,并且我使用 @RefreshScope 来启用该功能。

当我尝试在该服务中注入(inject) RestTemplate 的模拟时,问题就出现了,它似乎忽略它并使用 Autowiring 的实例。如果我注释掉注释,它似乎工作正常。

这是该服务的代码:

@Service
@RefreshScope
public class MyServiceImpl implements MyService {

private static final Logger LOG = Logger.getLogger(MyServiceImpl.class);

@Autowired
public RestTemplate restTemplate;

@Value("${opts.default}")
private String default;

@Value("${opts.address}")
private String address;

@Value("${opts.separator}")
private String separator;

...


}

测试源码:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class ServiceTest {

@Mock
private RestTemplate restTemplate;

@Autowired
@InjectMocks
private MyServiceImpl service;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}

public void testMethod() throws Exception {
when(restTemplate.postForObject(anyString(), any(), eq(ServiceResponse.class), anyMap())).thenReturn(getSuccessfulResponse());

ServiceResponse response = service.doYourStuff();

Assert.assertNotNull(response);
Assert.assertTrue(response.isSuccessful());
}

...
}

最佳答案

当添加@RefreshScope时,bean 成为代理而不是实际的原始实现。目前,RestTemplate 是在代理上设置的,而不是在底层实例上设置的。 (如果您进行调试,您会发现您的 MyServiceImpl 实际上更像是 MyServiceImpl$SpringCgLib#353234 的实例)。

要修复此问题,您需要使用 ReflectionTestUtilsAopTestUtils 手动设置依赖项。后者是获取实际的代理。

删除 @InjectMocks 注释,并在模拟初始化后将以下内容添加到 setup 方法中:

Object actualTarget = AopTestUtils.getUltimateTargetObject(service);
ReflectionTestUtils.setfield(actualTarget, "restTemplate", restTemplate);

对于 4.2 之前的版本,以下内容可能可以解决问题

Object actualTarget = (service instanceof Advised) ? ((Advised) service).getTargetSource().getTarget() : service;

问题是 Mockito 没有检测到代理,只是设置了该字段。 ReflectionTestUtils 也不会检测代理,因此需要手动展开。事实上,我之前曾多次陷入这个陷阱,这导致我创建了 SPR-14050今天早上将其嵌入到 ReflectionTestUtils 中以减轻一点痛苦。

关于java - @RefreshScope 似乎忽略了 Mockito 的模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35984395/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com