77

What is the difference between Mockito.mock(Class<T> classToMock) method and the @Mock annotation? Are they the same?

For Example, is this:

private TestClass test = Mockito.mock(TestClass.class);

the same as:

@Mock
private TestClass test;
Mureinik
  • 297,002
  • 52
  • 306
  • 350
Gábor Csikós
  • 2,787
  • 7
  • 31
  • 57

6 Answers6

92

They both achieve the same result. Using an annotation (@Mock) is usually considered "cleaner", as you don't fill up your code with boilerplate assignments that all look the same.

Note that in order to use the @Mock annotation, your test class should be annotated with @RunWith(MockitoJUnitRunner.class) or contain a call to MockitoAnnotations.initMocks(this) in its @Before method.

Alexander Ortiz
  • 529
  • 7
  • 14
Mureinik
  • 297,002
  • 52
  • 306
  • 350
13

The difference is in the lines of code you need to write :) :) :)

Seriously though, using the annotations has the exact same effect as using the Mockito.mock.

To quote the documentation of MockitoAnnotations the use of annotations has the following benefits:

  • Allows shorthand creation of objects required for testing.

  • Minimizes repetitive mock creation code.

  • Makes the test class more readable.

  • Makes the verification error easier to read because field name is
    used to identify the mock.

The javadoc for MockitoAnnotations is here

geoand
  • 60,071
  • 24
  • 172
  • 190
  • 1
    I find it strange to say shorthand. Yes, it requires fewer characters, but it requires more lines. – Roger C S Wernersson Mar 15 '17 at 11:37
  • 1
    In the context of software development shorthand I have always interpreted shorthand as meaning that I have to write less code :) – geoand Mar 15 '17 at 11:41
  • 4
    @RogerCSWernersson - you can put the annotation on the same line, annotations don't require a following newline. – Tasgall Aug 15 '17 at 19:20
8

There are two significant advantages to using the annotation.

  • A mock created with @Mock can be injected into the class you're testing, using the @InjectMocks annotation. This is a powerful technique that can make testing significantly easier. It just won't work with mocks created by the mock method.
  • If you have any errors involving your mock, the name of the mock will appear in the message. If you've used @Mock, then this name will just be the name of the field. This makes it really easy to find the problem mock.

Of course, in addition to these two important advantages, most people find the @Mock notation much more readable, and it does cut down on the amount of code. I see no reason not to use it.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
6

They both are considered same and achieve the same thing but I'd prefer the second one:

@Mock is an annotation which:

  • Minimizes repetitive mock creation code.
  • Makes the test class more readable.
  • Allows shorthand creation of objects required for testing.
Shweta
  • 121
  • 9
1

The answer of the question is one big mistake. We just solved some problems caused by Mockito.mock(Your.class) as a field. We had few @Test methods. The 4th method was throwing an exception with 'thenThrow(ex)'. All of the @Test methods after it was failing and the reason was the exception thrown. They were sharing the mocked instance and the 'when' condition. After we changed from

TestClass testInstance = Mockito.mock(TestClass.class);

to

@Mock
TestClass testInstance;

everything started to work as expected. So Mockito.mock is creating a shared mock between the test methods, and @Mock does not.

saferJo
  • 497
  • 1
  • 5
  • 16
  • 1
    This is incorrect. If you use `@Mock`, then you have to use `MockitoAnnotations.initMocks(this)` in the `@Before`, which is equivalent to just writing `Mockito.mock(Some.class)` in the same `@Before` setup method. (then the mock is recreated before each test and the problem you described goes away) – Andrejs Dec 28 '17 at 21:04
  • it may go away but thats a main difference. – saferJo Jan 02 '18 at 08:32
  • This is not true if you are using JUnit, it "creates a new instance of each test class before executing each test method" - https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-instance-lifecycle – Jezor Jan 21 '20 at 13:07
-3

In Junit5, use

@ExtendWith(MockitoExtension.class)
A. S. Ranjan
  • 355
  • 4
  • 4