【问题标题】:Can't pass mock to the inject mock service无法将模拟传递给注入模拟服务
【发布时间】:2021-10-12 07:35:07
【问题描述】:

我有服务:

@Service
class UserService {

   private final Map<AbstractSomeService, CustomEnum> someMap;

   public UserService(List<AbstractSomeService> someService) {
     someService.forEach(service -> someMap.put(service.getCustomEnum(), service));
    }

  public void logicExecution() {
     //code
  }
}

当我模拟如下:我得到 NullPointer:

@Mock
private SomeService someService;  // Service which is extended of AbstractSomeService

@InjectMocks
private UserService userService = new UserService(Collection.singletonList(someService))

@BeforeEach
void setUp() {
   MockitoAnnotations.openMocks(this);
}

@Test
public void testBrokenJunit() {
  userService.logicExecution(); // NULL POINTER HERE (
}

一些服务:

@Service
public class SomeService extends AbstactSomeService() {
  
  public CustomEnum getCustomEnum() {
      return CustomEnum.BROKEN_JUNIT_TEST;
  }
  //logic here
}

堆栈跟踪非常简单:

java.lang.NullPointerException: Cannot invoke "getCustomEnum()" because "service" is null

没有构造函数初始化的StackTrace:

org.mockito.exceptions.misusing.InjectMocksException: 
Cannot instantiate @InjectMocks field named 'UserService' of type '...'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : Cannot invoke "java.util.List.forEach(java.util.function.Consumer)" because "someService" is null

at 

Caused by: java.lang.NullPointerException: Cannot invoke "java.util.List.forEach(java.util.function.Consumer)" because "someService" is null
    at UserService.<init>

附言

当我使用 UserService 的真实对象时,不是模拟一切都可以。

但它不适用于@InjectMocks

【问题讨论】:

  • 尝试在用户参考中使用@MockBean
  • 能否添加完整的测试代码?谢谢!
  • @JoãoDias 添加了“SomeService”的代码,并更新了代码
  • 请同时发布堆栈跟踪,以便我们了解发生了什么。
  • 我有一个类似的问题,当我注入的一个 Mocks 是 InjectMocks 的构造函数中的一个实现时。如果其他人有类似的问题,请尝试将实现更改为构造函数中的接口。

标签: java spring junit mockito


【解决方案1】:

在您的测试类中尝试以下操作(您无需通过构造函数使用新实例初始化 UserService@InjectMocks 将为您完成):

@Mock
private SomeService someService;

@InjectMocks
private UserService userService;

@BeforeEach
void setUp() {
   MockitoAnnotations.openMocks(this);
}

@Test
public void testBrokenJunit() {
  userService.logicExecution();
}

如果这不起作用,因为您有一个 List 而不是一个简单的 SomeService,您可以执行以下操作:

@Mock
private SomeService someService;

private UserService userService;

@BeforeEach
void setUp() {
   MockitoAnnotations.openMocks(this);
   userService = new UserService(Collection.singletonList(someService));
}

@Test
public void testBrokenJunit() {
  userService.logicExecution();
}

【讨论】:

  • 对于我使用开放式模拟的模拟初始化,请检查更新的代码。但我不相信这是一个问题。可能问题与 Mocks 在构造函数中不起作用有关
  • 我的错。请检查我编辑的答案。你不需要实例化UserService@InjectMocks 会为你做到这一点。
  • 如果我要删除构造函数,mockito 会说他没有找到实例并试图创建它,但得到了异常
  • 检查我的其他可能的解决方案 ;)
  • 是的,它有效,但我在 P.S. 中这么说。 ) 但它不是一个模拟,一个真实的对象
【解决方案2】:

使用@MockBean 创建模拟对象

import org.springframework.boot.test.mock.mockito.MockBean;

@MockBean
private User user;

【讨论】:

  • 我的错,改变了代码视图,我确实将抽象类传递给构造函数而不是一些 DTO
猜你喜欢
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-31
  • 1970-01-01
  • 2019-04-18
  • 2015-12-02
相关资源
最近更新 更多