Java 在Junit测试中,当I@Autowired用于接口时获取null

Java 在Junit测试中,当I@Autowired用于接口时获取null,java,spring,junit,Java,Spring,Junit,我正在为这个方法编写JUnit测试processData——我正在JUnit中进行@AutowiredCache mycache,并在我的测试方法下模拟Cache mycache。当我执行此操作时,mycache=mock(Cache.class)-这会在Junit方法中返回一些对象,但当我从JunitCache mycache调用我的实际方法时,在Main类中变为null。请查找以下代码: 这里我缺少的是——如何解决这个NullPointer异常问题——为什么当实际方法从Junit触发时myc

我正在为这个方法编写JUnit测试
processData
——我正在JUnit中进行
@Autowired
Cache mycache
,并在我的测试方法下模拟
Cache mycache
。当我执行此操作时,
mycache=mock(Cache.class)
-这会在Junit方法中返回一些对象,但当我从Junit
Cache mycache
调用我的实际方法时,在
Main
类中变为null。请查找以下代码:

这里我缺少的是——如何解决这个NullPointer异常问题——为什么当实际方法从Junit触发时mycache变为null——尽管我已经模拟了这个对象。任何帮助都将不胜感激。谢谢大家!

Main.Java

import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Main {

    @Autowired
    Cache mycache;

    public Product processData(String productId) {

    System.out.println("productId value: " +productId);
    System.out.println("mycache value: " +mycache);

        Product product = (Product) mycache.getIfPresent(productId); //getting NullPointer exception here
        if (product != null) {
            return product;
        }
        // do some processing
        return product;
    }
}
public class MainTest {
    @Autowired
    Cache mycache;

    @Test
    public void processDataTest() throws Exception {
        Main main = new Main();
        mycache = mock(Cache.class);
        System.out.println("mycache: " + mycache.toString()); // Mock for Cache, hashCode: 3244883
        when(mycache.getIfPresent("9393939")).thenReturn(null);
        Product product = main.processData("9393939");
        assertNotNull(product);
    }
}
MainTest.Java

import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Main {

    @Autowired
    Cache mycache;

    public Product processData(String productId) {

    System.out.println("productId value: " +productId);
    System.out.println("mycache value: " +mycache);

        Product product = (Product) mycache.getIfPresent(productId); //getting NullPointer exception here
        if (product != null) {
            return product;
        }
        // do some processing
        return product;
    }
}
public class MainTest {
    @Autowired
    Cache mycache;

    @Test
    public void processDataTest() throws Exception {
        Main main = new Main();
        mycache = mock(Cache.class);
        System.out.println("mycache: " + mycache.toString()); // Mock for Cache, hashCode: 3244883
        when(mycache.getIfPresent("9393939")).thenReturn(null);
        Product product = main.processData("9393939");
        assertNotNull(product);
    }
}
异常日志跟踪:

mycache: Mock for Cache, hashCode: 3244883
        productId value: 9393939
        mycache value: null

        java.lang.NullPointerException
        at com.test.processData(Main.java:122)
        at com.test.MainTest.processDataTest(MainTest.java:161)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)

如果您的测试用例中有一个类
@Autowired
,那么您不应该模拟它。您需要使用
@Mock
注释缓存字段,否则将无法模拟Cache.class

processData处变为null的原因是缓存对象是自动连接的,而不是模拟的

java.lang.NullPointerException
        at com.test.processData(Main.java:122)
你能试试下面的代码吗

public class MainTest {

    @Mock
    Cache mycache;

    @Test
    public void processDataTest() throws Exception {
        Main main = new Main();
        // mycache = mock(Cache.class);
        System.out.println("mycache: " + mycache.toString()); // Mock for Cache, hashCode: 3244883
        when(mycache.getIfPresent("9393939")).thenReturn(null);
        Product product = main.processData("9393939");
        assertNotNull(product);
    }
}

如果您的测试用例中有一个类
@Autowired
,那么您不应该模拟它。您需要使用
@Mock
注释缓存字段,否则将无法模拟Cache.class

processData处变为null的原因是缓存对象是自动连接的,而不是模拟的

java.lang.NullPointerException
        at com.test.processData(Main.java:122)
你能试试下面的代码吗

public class MainTest {

    @Mock
    Cache mycache;

    @Test
    public void processDataTest() throws Exception {
        Main main = new Main();
        // mycache = mock(Cache.class);
        System.out.println("mycache: " + mycache.toString()); // Mock for Cache, hashCode: 3244883
        when(mycache.getIfPresent("9393939")).thenReturn(null);
        Product product = main.processData("9393939");
        assertNotNull(product);
    }
}
而不是做:

@Component
public class Main {

   @Autowired
   Cache mycache;
   ...
通过构造函数注入它:

  @Component
  public class Main {
      private final Cache mycache;

      public Main(Cache mycache) {
          this.mycache = mycache;
      }
  }
现在,您可以创建
Main
的实例,在该实例中,您可以提供
缓存的模拟,而不是执行以下操作:

@Component
public class Main {

   @Autowired
   Cache mycache;
   ...
通过构造函数注入它:

  @Component
  public class Main {
      private final Cache mycache;

      public Main(Cache mycache) {
          this.mycache = mycache;
      }
  }

现在,您可以创建
Main
的实例,在该实例中,您可以提供
缓存的模拟

@Autowired-Cache-mycache这在您的类中无效。应该由谁来解决该
@Autowired
?然后再执行
mycache=mock(Cache.class)?这毫无意义。我在我的主类中使用咖啡因库(com.github.benmanes.caffee.Cache.Cache)中的缓存,如何在junit测试类下使用这个缓存对象?
@Autowired Cache-mycache这在您的类中无效。应该由谁来解决该
@Autowired
?然后再执行
mycache=mock(Cache.class)?这毫无意义。我在我的主类中使用咖啡因库(com.github.benmanes.caffee.Cache.Cache)中的缓存,如何在junit测试类下使用这个缓存对象?这是如何
@Autowired Main应该解决吗?这个答案毫无意义,因为它解决了问题,我也尝试了你的选择,即使这样也有效。谢谢你的帮助@Eugene@LearningJava如何"解决问题"??没有spring上下文可以提供
@Autowired
-
main
将始终为null。@Eugene,我只添加了Autowired on main类,因为它是用组件注释的,所以最好在测试用例中插入而不是初始化对象。我提供的答案是假设spring上下文将出现,因为主类被注释为组件。我也被类名弄糊涂了,但似乎这是作者添加的,只是作为一个例子。在
Main
类上什么注释是无关紧要的,因为
MainTest
没有弹簧注释。这是怎么回事
@autowiredmain应该解决吗?这个答案毫无意义,因为它解决了问题,我也尝试了你的选择,即使这样也有效。谢谢你的帮助@Eugene@LearningJava如何"解决问题"??没有spring上下文可以提供
@Autowired
-
main
将始终为null。@Eugene,我只添加了Autowired on main类,因为它是用组件注释的,所以最好在测试用例中插入而不是初始化对象。我提供的答案是假设spring上下文将出现,因为主类被注释为组件。我也被类名弄糊涂了,但这似乎是作者添加的,只是作为一个例子。在
Main
class上什么注释是无关紧要的,因为
MainTest
没有spring注释。