java - 使用mockito更改 Final 字段

标签 java mockito junit5 powermockito

我在模拟类的最后一个字段时遇到了mockito问题,你们能帮忙解决这个问题吗

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");

 }

现在,当在 Debug模式下运行时,这显示我将值更改为 XYZ,但不适用于 if 条件始终进入 else block ,尽管在 Debug模式下显示 XYZ。

最佳答案

基本上,您正在走入非常错误的兔子洞。将这么多东西放在一起不是一个好主意。

首先,Mockito(以及所有其他模拟框架)旨在用于行为,而不是状态。换句话说。尽管您的模拟对象实际上具有该字段,但请记住:它仍然是一个模拟对象。您不会找到太多文档或教程来告诉您模拟框架将如何处理模拟对象的字段和字段值。

更糟糕的是,真正的问题是:您没有模拟被测试的类。您可以使用模拟来控制被测代码正在使用的其他对象。模拟和测试同一个对象根本没有(多大)意义!

然后:不要将反射与基于“模拟”的单元测试一起使用,尤其是不要“反射”模拟对象。如前所述:这些框架会做他们认为必要的任何事情,因此即使某些代码现在可以工作,新版本的 Mockito 也很可能会更改此类内部结构,并导致此类代码在将来失败。

接下来,请注意您的代码一开始就毫无意义:

public final String VALUE= "ABC";
public String someMethod(){
  if (!VALUE.equals("ABC")){ ## IF NOT WORKING

VALUE 始终为 ABC,因此您始终会得到 if(!true)。那么在代码中使用 if 语句是没有意义的。

因此,如果您确实需要这种类型的开关,您可以将其设为方法调用,例如:

  public String someMethod(){
    if (reallyDoIt())) ...

 boolean reallyDoIt() { return ...

重点是:现在您可以使用 Mockito 的 spy 概念来测试您的 someMethod() 调用。通过这样做,您可以指示 Mockito “真正”调用 someMethod(),但返回 reallyDoIt() 的虚假答案。更多详情请参见here例如。

除此之外,我强烈建议您退后一步,阅读有关 Mockito 的优秀教程,例如 vogella 中的教程。 。很简单,因为您的代码意味着您并不真正了解如何在单元测试中使用模拟框架。

关于java - 使用mockito更改 Final 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57900014/

相关文章:

Java线程似乎无法正常运行

java - 如何将静态网页内容(js/css)添加到嵌入式 jetty ?

java - 如何验证未引发异常

spring-boot - Spring Boot Kotlin Mockito @MockBean 依赖在方法调用上抛出 IllegalStateException null

unit-testing - Junit5模拟静态方法

java - 如何检查 java.lang.AssertionError (JUnit 5)

java - 如何使 Spring 的 @Autowired 在 JUnit 5 扩展中工作?

java - 直接从 JComponent 重写paintComponent

java - 如何等待页面加载后再执行下一步操作?

java - Mockito ArgumentCaptor 验证没有捕获任何内容