
Inline adoc files when they are included exactly once. Also fix language tags because this inlining gives us better information on what language the code is written in.
185 lines
4.4 KiB
Plaintext
185 lines
4.4 KiB
Plaintext
== Why is this an issue?
|
||
|
||
Objects annotated with Mockito annotations ``++@Mock++``, ``++@Spy++``, ``++@Captor++``, or ``++@InjectMocks++`` need to be initialized explicitly.
|
||
|
||
|
||
There are several ways to do this:
|
||
|
||
* Call ``++MockitoAnnotations.openMocks(this)++`` or ``++MockitoAnnotations.initMocks(this)++`` in a setup method
|
||
* Annotate test class with ``++@RunWith(MockitoJUnitRunner.class)++`` (JUnit 4)
|
||
* Annotate test class with ``++@ExtendWith(MockitoExtension.class)++`` (JUnit 5 Jupiter)
|
||
* Use ``++@Rule public MockitoRule rule = MockitoJUnit.rule();++``
|
||
|
||
Test using uninitialized mocks will fail.
|
||
|
||
|
||
Note that this only applies to annotated Mockito objects. It is not necessary to initialize objects instantiated via ``++Mockito.mock()++`` or ``++Mockito.spy()++``.
|
||
|
||
|
||
This rule raises an issue when a test class uses uninitialized mocks.
|
||
|
||
|
||
=== Noncompliant code example
|
||
|
||
[source,java]
|
||
----
|
||
public class FooTest { // Noncompliant: Mockito initialization missing
|
||
@Mock private Bar bar;
|
||
|
||
@Spy private Baz baz;
|
||
|
||
@InjectMocks private Foo fooUnderTest;
|
||
|
||
@Test
|
||
void someTest() {
|
||
// test something ...
|
||
}
|
||
|
||
@Nested
|
||
public class Nested {
|
||
@Mock
|
||
private Bar bar;
|
||
}
|
||
----
|
||
|
||
|
||
=== Compliant solution
|
||
|
||
[source,java]
|
||
----
|
||
@RunWith(MockitoJUnitRunner.class)
|
||
public class FooTest {
|
||
@Mock private Bar bar;
|
||
// ...
|
||
}
|
||
----
|
||
|
||
[source,java]
|
||
----
|
||
@ExtendWith(MockitoExtension.class)
|
||
public class FooTest {
|
||
@Mock private Bar bar;
|
||
// ...
|
||
}
|
||
----
|
||
|
||
[source,java]
|
||
----
|
||
public class FooTest {
|
||
@Rule
|
||
public MockitoRule rule = MockitoJUnit.rule();
|
||
|
||
@Mock private Bar bar;
|
||
// ...
|
||
}
|
||
----
|
||
|
||
[source,java]
|
||
----
|
||
public class FooTest {
|
||
@Mock private Bar bar;
|
||
// ...
|
||
|
||
@BeforeEach
|
||
void setUp() {
|
||
MockitoAnnotations.openMocks(this);
|
||
}
|
||
// ...
|
||
}
|
||
----
|
||
|
||
[source,java]
|
||
----
|
||
public class FooTest {
|
||
@Mock private Bar bar;
|
||
// ...
|
||
|
||
@Before
|
||
void setUp() {
|
||
MockitoAnnotations.initMocks(this);
|
||
}
|
||
// ...
|
||
}
|
||
----
|
||
|
||
[source,java]
|
||
----
|
||
@ExtendWith(MockitoExtension.class)
|
||
public class FooTest {
|
||
@Nested
|
||
public class Nested {
|
||
@Mock
|
||
private Bar bar;
|
||
}
|
||
}
|
||
----
|
||
|
||
|
||
== Resources
|
||
|
||
* https://site.mockito.org/javadoc/current/org/mockito/MockitoAnnotations.html[Mockito documentation - MockitoAnnotations]
|
||
* https://site.mockito.org/javadoc/current/org/mockito/junit/MockitoRule.html[Mockito documentation - MockitoRule ]
|
||
|
||
|
||
ifdef::env-github,rspecator-view[]
|
||
|
||
'''
|
||
== Implementation Specification
|
||
(visible only on this page)
|
||
|
||
=== Message
|
||
|
||
Initialize mocks before using them.
|
||
|
||
|
||
=== Highlighting
|
||
|
||
Primary:
|
||
|
||
The first ``++@Mock++``, ``++@Spy++``, ``++@Captor++``, ``++@InjectMocks++`` annotation
|
||
|
||
|
||
No need for secondaries. They won't provide any additional value.
|
||
|
||
|
||
'''
|
||
== Comments And Links
|
||
(visible only on this page)
|
||
|
||
=== on 4 Sep 2020, 17:14:44 Nicolas Harraudeau wrote:
|
||
Note that this is a low priority rule as tests would fail if this bug is present. It can however be useful for SonarLint users as they will be able to see their mistake more rapidly. It won't add much value for SonarQube/SonarCloud users.
|
||
|
||
=== on 15 Mar 2021, 23:23:53 Nicolas Coquelet wrote:
|
||
Hi,
|
||
|
||
|
||
This rule throw a false positive on test class annotated with @MockitoSettings.
|
||
|
||
|
||
The official documentation describe that if we use @MockitoSettings annotation to configure Mockito behaviour, we can avoid @ExtendWith(MockitoExtension.class) annotation
|
||
|
||
|
||
Here the official documentation link
|
||
|
||
https://www.javadoc.io/static/org.mockito/mockito-junit-jupiter/3.8.0/org/mockito/junit/jupiter/MockitoExtension.html
|
||
|
||
|
||
|
||
=== on 17 Mar 2021, 12:05:23 Quentin Jaquier wrote:
|
||
Hello [~ncoquelet]
|
||
|
||
|
||
First, let me just warn you that commenting on a closed ticket (SONARJAVA-3606) or directly in the RSPEC description is not the best way to get attention as nobody is actively monitoring these places, it is too easy to get unnoticed. The recommended way to go is the https://community.sonarsource.com/[community forum].
|
||
|
||
|
||
As long as I am here, let me answer your question here anyway:
|
||
|
||
What you suggest makes sense to me, and in fact, we recently created SONARJAVA-3734. Since the annotation you are talking about is itself a meta-annotation annotated with ``++@ExtendWith(value=MockitoExtension.class)++``, this ticket should solve your concern as well. I added a point in the description to make sure we test this.
|
||
|
||
|
||
Have a great day,
|
||
|
||
Quentin
|
||
|
||
endif::env-github,rspecator-view[]
|