Java 在Junit测试中,当I@Autowired用于接口时获取null
我正在为这个方法编写JUnit测试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
processData
——我正在JUnit中进行@Autowired
Cache mycache
,并在我的测试方法下模拟Cache mycache
。当我执行此操作时,mycache=mock(Cache.class)
-这会在Junit方法中返回一些对象,但当我从JunitCache 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注释。