On Thu, Mar 16, 2017 at 8:36 PM, Allon Mureinik <amureini(a)redhat.com> wrote:
The root cause seems to be MigrateVmCommandTest and its relation to
MigrateVmCommand.
A common misconception is that if an object is annotated with
@InjectMocks, Mockito will inject its @Mocks and @Spys to fields annotated
with @Inject.
This is, as noted, not correct - Mockito will attempt to injcet its mocks
to *ALL* the fields, regardless of annotations.
And here's where things start getting funky.
Since the new field you introduced is an Object, any mock would be a
possible match for it. If more than one mock fits the field (as you have in
the test - dbFacade and vmValidator), Mockito silently skips injecting it,
and leaves it null (not sure if this is a bug or an intentional ugly
behavior) - need to look into this further.
Even worse, this failure breaks the mocking sequence, so the mocked object
isn't spied. When you attempt to stub it's behavior (e.g., with doReturn,
as the first line of testValidationFailsWhenVmHasDisksPluggedWithScsiReservation
does), it will fail with a NotAMockException). From there on, it's all down
hill.
The good news is that this test doesn't really need to inject mocks, so
just removing that annotation solves the issue. I've posted a patch [1],
please review it.
I'll also organize an MCVE reproducer and report a bug against mockito,
and we'll see if there's any chance to get it solved any time soon.
-Allon
[1]
https://gerrit.ovirt.org/#/q/topic:MigrateVmCommandTest
On Thu, Mar 16, 2017 at 11:55 AM, Shmuel Melamud <smelamud(a)redhat.com>
wrote:
> Hi!
>
> I've found yesterday a very strange bug, most likely in Mockito. Hard
> to believe it really happens, but I've reproduced it in different
> environmentы and several revisions of oVirt master.
>
> I've added the following line into MigrateVmCommand:
>
> private Integer actualDowntime;
> + private Object actualDowntimeLock;
>
> This line causes ALL tests to fail with NullPointerException. Some
> tests print such a stack trace:
>
> java.lang.NullPointerException
> at org.mockito.internal.junit.util.TestName.getTestName(TestNam
> e.java:11)
> at org.mockito.internal.junit.MismatchReportingTestListener.tes
> tFinished(MismatchReportingTestListener.java:29)
> at org.mockito.internal.runners.DefaultInternalRunner$1$1.testF
> inished(DefaultInternalRunner.java:56)
> at org.junit.runner.notification.SynchronizedRunListener.testFi
> nished(SynchronizedRunListener.java:56)
> at org.junit.runner.notification.RunNotifier$7.notifyListener(R
> unNotifier.java:190)
> ...
>
> Name of the field doesn't matter, but type matters - changing the type
> to Integer solved the problem.
>
> Does anybody has an idea why this happens and how to fix it?
>
> Shmuel
> _______________________________________________
> Devel mailing list
> Devel(a)ovirt.org
>
http://lists.ovirt.org/mailman/listinfo/devel