Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using @Mock and @InjectMocks

I'm currently studying the Mockito framework and I've created several test cases using Mockito. But then I read that instead of invoking mock(SomeClass.class) I can use the @Mock and the @InjectMocks - The only thing I need to do is to annotate my test class with @RunWith(MockitoJUnitRunner.class) or use the MockitoAnnotations.initMocks(this); in the @Before method.

But it doesn't work - It seems that the @Mock won't work! Here is my 2 codes revisions - one using the annotations and one without.

What am I doing wrong?

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 } 

As I said - this work great. But the following wont:

@RunWith(MockitoJUnitRunner.class) public class ReportServiceImplTestMockito {       @Mock       private TaskService      mockTaskService;       @InjectMocks       private ReportServiceImpl service;           // Some tests } 

And here is the ReportServiceImpl class:

@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;     } } 

What am I missing?

like image 460
Noam Avatar asked Jan 31 '12 08:01

Noam


People also ask

Can we use mock and InjectMocks together?

A mock doesn't have any real implementation. @InjectMocks would try to find and call setters for whatever mock objects have already been created and pass them in.

What is the use of @mock annotation?

@Mock: It is used to mock the objects that helps in minimizing the repetitive mock objects. It makes the test code and verification error easier to read as parameter names (field names) are used to identify the mocks. The @Mock annotation is available in the org. mockito package.

What is the use of @InjectMocks annotation?

@InjectMocks is the Mockito Annotation. It allows you to mark a field on which an injection is to be performed. Injection allows you to, Enable shorthand mock and spy injections.

What is the difference between @mock and @MockBean?

We can use the @MockBean to add mock objects to the Spring application context. The mock will replace any existing bean of the same type in the application context. If no bean of the same type is defined, a new one will be added.


2 Answers

O.K, I got my mistake!!! I've used the @InjectMocks but initialized the same variable in the init() method... So what happened was that mockito injected the mock objects to my variable - but seconds later I ran it over - initializing that very same variable!!!

like image 172
Noam Avatar answered Oct 06 '22 21:10

Noam


Your code works fine for me using Mockito 1.9.

Using an 1.8+ version of Mockito I get a very specific error message telling me exactly how to fix the problem. As php-coder suggests: For Mockito 1.8+ you need to initialize the field.

Did you see this or any other error message?

Edit:

The following code works for me. Small changes:

  • Removed Spring annotations
  • Removed Interface
  • Added Getter
  • Added empty TaskService
  • Added test with System.out.println

Does it produce an error for you? :

Service:

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;     } } 

Dependency:

public class TaskService {  } 

Test, prints mockTaskService:

@RunWith(MockitoJUnitRunner.class) public class ReportServiceImplTestMockito {      @Mock     private TaskService       mockTaskService;      @InjectMocks     private ReportServiceImpl service;       @Test     public void testMockInjected() {         System.out.println(service.getTaskServiceImpl());     } } 
like image 20
Arend v. Reinersdorff Avatar answered Oct 06 '22 21:10

Arend v. Reinersdorff