Java 使用mockito更改最终字段
我在模拟一个类的最后一个字段时遇到了一个问题,你们能帮我吗Java 使用mockito更改最终字段,java,mockito,junit5,powermockito,Java,Mockito,Junit5,Powermockito,我在模拟一个类的最后一个字段时遇到了一个问题,你们能帮我吗 public class Product{ public final String VALUE= "ABC"; public String someMethod(){ if (!VALUE.equals("ABC")){ ## IF NOT WORKING //inside if condition }else{ //inside else condition
public class Product{
public final String VALUE= "ABC";
public String someMethod(){
if (!VALUE.equals("ABC")){ ## IF NOT WORKING
//inside if condition
}else{
//inside else condition
}
}
}
//Test Class
@test
public void test_someMethod(){
Product product = Mockito.mock(Product.class,"Product");
Field field = Product.class.getDeclaredField("VALUE");
field.setAccessible(true);
ReflectionUtils.setField(field, product , "XYZ");
}
现在,在调试模式下运行时,这会将值显示为XYZ,但如果条件始终在else块中,则不起作用,尽管在调试模式下显示XYZ。基本上,您在这里遇到了非常错误的兔子洞。把这么多东西放在一起不是个好主意 首先,Mockito(以及所有其他mocking框架)旨在用于行为,而不是状态。换句话说。尽管您的模拟对象实际上具有该字段,但请记住:它仍然是一个模拟对象。您不会找到很多文档或教程来告诉您模拟框架将如何处理模拟对象的字段和字段值 更糟糕的是,真正的问题是:你没有嘲笑你被测试的类。您可以使用mock来控制测试代码正在使用的其他对象。模拟和测试同一个对象根本没有意义 然后:不要将反射与基于“模拟”的单元测试一起使用,尤其不要在模拟对象上“反射”。如前所述:这些框架做他们认为必要的任何事情,因此即使一些代码在今天工作,Mockito的新版本也有可能改变这些内部结构,并在将来导致这些代码失败 接下来,请注意,您的代码一开始就毫无意义:
public final String VALUE= "ABC";
public String someMethod(){
if (!VALUE.equals("ABC")){ ## IF NOT WORKING
值始终是ABC,因此如果(!true),则始终以结束。在代码中使用if语句是没有意义的
因此,如果您真的需要此类开关,您可以将其作为方法调用,如:
public String someMethod(){
if (reallyDoIt())) ...
与
要点是:现在您可以使用Mockito的spy概念来测试someMethod()
调用。通过这样做,您可以指示Mockito“真的”调用someMethod()
,但为reallyDoIt()
返回假答案。有关更多详细信息,请参见示例
除此之外,我强烈建议您退后一步,阅读一本关于Mockito的好教程,就像来自。这仅仅是因为您的代码意味着您并不真正了解如何在单元测试中使用模拟框架 谢谢。。详细解释。但对我来说,这里的限制不是更改基本代码(即somemethod())
boolean reallyDoIt() { return ...