问题描述
我正在尝试使用 Quarkus 应用程序中的 FieldSetter 将值设置为我的测试类中的私有字段(Quarkus 版本:1.5.2.Final 和 JDK 版本:11)
主类
@ApplicationScoped
public class TokenService{
@Inject @RestClient RestClientInterface client;
private String someVariable;
public String someMethod(){}
}
测试类
@QuarkusTest
public class TokenServiceTest{
@Inject TokenService service;
@InjectMock @RestClient RestClientInterface client;
@Test
public void someMethodtest(){
FieldSetter.setField(service,"someVariable","someValue");
}
}
但是 FieldSetter 抛出 NoSuchField 错误。请帮忙。 也试过
service.getClass().getdeclaredField("someVariable")
但同样的问题。
提前致谢。
解决方法
TokenService
类是 @ApplicationScoped
。这意味着如果您在某处@Inject
它,则不会直接注入该类的实例。相反,注入的是所谓的客户端代理,它是原始类的子类。该子类负责在每次方法调用时查找正确的实例(并将调用转发给实例)。
这个子类自然不声明someVariable
。这就是 getDeclaredField("someVariable")
失败的原因。我假设 FieldSetter
来自 Mockito —— 在这种情况下,它会做同样的事情并且由于同样的原因失败。
您可以将 TokenService
设为 @Singleton
-- 在这种情况下,没有客户端代理并直接注入实例 -- 或者使用客户端代理是子类的知识并简单地查看在一个超类。或者——这可能是最好的——重新设计你的代码,这样你就不必从外部更改 private
字段。无论如何,这是一种代码气味。