【问题标题】:Using @Mock and @InjectMocks使用@Mock 和@InjectMocks
【发布时间】:2012-01-31 08:09:48
【问题描述】:

我目前正在研究 Mockito 框架,并使用 Mockito 创建了几个测试用例。 但后来我读到,我可以使用 @Mock@InjectMocks 而不是调用 mock(SomeClass.class) - 我唯一需要做的就是用 @987654323 注释我的测试类@ 或在@Before 方法中使用MockitoAnnotations.initMocks(this);

但它不起作用 - @Mock 似乎不起作用! 这是我的 2 个代码修订版 - 一个使用注释,一个没有。

我做错了什么?

public class ReportServiceImplTestMockito {

    private TaskService       mockTaskService; // This is the Mock object
    private ReportServiceImpl service;

    @Before
    public void init(){
        service         = new ReportServiceImpl();
        mockTaskService = mock(TaskServiceImpl.class);
        service.setTaskServiceImpl(mockTaskService);
    }
/// ...

 Some tests
}

正如我所说 - 这工作很棒。 但以下不会:

@RunWith(MockitoJUnitRunner.class)
public class ReportServiceImplTestMockito {

     @Mock 
     private TaskService      mockTaskService;

     @InjectMocks 
     private ReportServiceImpl service;

         // Some tests
}

这里是ReportServiceImpl 类:

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private TaskService taskServiceImpl;

    public ReportServiceImpl(){}

    public ReportServiceImpl(TaskService taskService){
        this.taskServiceImpl = taskService;
    }

    public void setTaskServiceImpl(TaskService taskServiceImpl) {
        this.taskServiceImpl = taskServiceImpl;
    }
}

我错过了什么?

【问题讨论】:

  • 乍一看对我来说还不错。你到底出了什么问题?
  • @Noam 你确定你使用的是正确的导入吗?
  • David - 我收到 NullPointerException。还有 Brice,我相信我使用了正确的导入 - 这里它们是 'import org.jmock.auto.Mock;导入 org.junit.runner.RunWith;导入 org.mockito.InjectMocks;导入 org.mockito.MockitoAnnotations;导入 org.mockito.runners.MockitoJUnitRunner;'

标签: java mocking mockito


【解决方案1】:

好吧,我搞错了!!! 我使用了@InjectMocks,但在 init() 方法中初始化了相同的变量... 所以发生的事情是,mockito 将模拟对象注入到我的变量中 - 但几秒钟后我运行了它 - 初始化了同一个变量!!!

【讨论】:

  • 感谢上帝这个问题和自我实现的答案。我正在失去我的头发。
【解决方案2】:

您的代码在我使用 Mockito 1.9 时运行良好。

使用 1.8+ 版本的 Mockito,我收到一条非常具体的错误消息,告诉我如何解决问题。正如 php-coder 建议的那样:对于 Mockito 1.8+,您需要初始化该字段。

您是否看到此错误消息或任何其他错误消息?

编辑:

以下代码对我有用。小改动:

  • 删除了 Spring 注释
  • 已移除接口
  • 添加了 Getter
  • 添加空TaskService
  • 添加了System.out.println的测试

它会为您产生错误吗? :

服务:

public class ReportServiceImpl {

    private TaskService taskServiceImpl;


    public ReportServiceImpl() {

    }


    public ReportServiceImpl(TaskService taskService) {
        this.taskServiceImpl = taskService;
    }


    public void setTaskServiceImpl(TaskService taskServiceImpl) {
        this.taskServiceImpl = taskServiceImpl;
    }


    public TaskService getTaskServiceImpl() {
        return taskServiceImpl;
    }
}

依赖:

public class TaskService {

}

测试,打印mockTaskService

@RunWith(MockitoJUnitRunner.class)
public class ReportServiceImplTestMockito {

    @Mock
    private TaskService       mockTaskService;

    @InjectMocks
    private ReportServiceImpl service;


    @Test
    public void testMockInjected() {
        System.out.println(service.getTaskServiceImpl());
    }
}

【讨论】:

  • 正如我所说,代码对我有用。你能测试我发布的代码吗(仅限小改动)?
  • 嗨 Arend,抱歉耽搁了 - 但你的代码也适用于我,我已经为 @Mock 注释使用了磨损导入 - import org.mockito.MockitoAnnotations;而不是导入 org.mockito.Mock;
【解决方案3】:

我不确定,但请尝试手动创建 ReportServiceImpl 的新实例(就像您在工作示例中所做的那样):

 @InjectMocks 
 private ReportServiceImpl service = new ReportServiceImpl();

【讨论】:

  • 自 Mockito 1.9 以来,除边缘情况外,这不再是必要的了。
  • 如果您使用的是 1.8,则需要在初始化程序或构造函数中对其进行实例化,除非您使用的是 MockitoAnnotations.initMocks(this),在这种情况下,您需要在调用之前对其进行实例化。
  • 首先,感谢您的回复。但是使用 MockitoAnnotations.initMocks(this) 不是必需的,因为我使用了@RunWith(MockitoJUnitRunner.class)。
猜你喜欢
  • 1970-01-01
  • 2023-01-18
  • 2013-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多