0

I have the following piece of code:

PowerMockito.mockStatic(DateUtils.class);      
//And this is the line which does the exception - notice it's a static function  
PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);

The class begins with:
@RunWith(PowerMockRunner.class) @PrepareForTest({CM9DateUtils.class,DateUtils.class})

And I get org.Mockito.exceptions.InvalidUseOfMatchersException...... You cannot use argument matchers outside of verification or stubbing..... (The error appears twice in the Failure Trace - but both point to the same line)

In other places in my code the usage of when is done and it's working properly. Also, when debugging my code I found that any(Date.class) returns null.

I have tried the following solutions which I saw other people found useful, but for me it doesn't work:

  1. Adding @After public void checkMockito() { Mockito.validateMockitoUsage(); }
    or
    @RunWith(MockitoJUnitRunner.class)
    or
    @RunWith(PowerMockRunner.class)

  2. Change to PowerMockito.when(new Boolean(DateUtils.isEqualByDateTime(any(Date.class), any(Date.class)))).thenReturn(false);

  3. Using anyObject() (it doesn't compile)

  4. Using notNull(Date.class) or (Date)notNull()

  5. Replace when(........).thenReturn(false);

    with
    Boolean falseBool=new Boolean(false);
    and
    when(.......).thenReturn(falseBool);

Achi Even-dar
  • 427
  • 1
  • 10
  • 20
  • Without a testable example, and noting the clarification mentioned below as a comment, I don't think this question has enough detail to be answerable or useful to future readers. Please consider adding more detail. (Note that Mockito matchers carry state, so you can get similar exceptions simply by trying to 'save matcher values' to local variables, and Mockito will not tell you this until a stubbing/verification call much later. Posting your surrounding code is crucial to diagnose matcher problems.) – Jeff Bowman Jun 30 '15 at 09:18

3 Answers3

2

As detailed on the PowerMockito Getting Started Page, you'll need to use both the PowerMock runner as well as the @PrepareForTest annotation.

@RunWith(PowerMockRunner.class)
@PrepareForTest(DateUtils.class)

Ensure that you're using the @RunWith annotation that comes with JUnit 4, org.junit.runner.RunWith. Because it's always accepted a value attribute, it's pretty odd to me that you're receiving that error if you're using the correct RunWith type.

any(Date.class) is correct to return null: Rather than using a magic "matches any Date" instance, Mockito uses a hidden stack of matchers to track which matcher expressions correspond to matched arguments, and returns null for Objects (and 0 for integers, and false for booleans, and so forth).

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • Ok, so seems I forgot to import the "RunWith", but still, after importing it and getting over the compilation error, still I get the same exception. – Achi Even-dar Jun 30 '15 at 06:31
  • Also, I did not mention it in the original post (now edited), but this @PrepareForTest(DateUtils.class) is used in my code – Achi Even-dar Jun 30 '15 at 06:44
0

So in the end,what worked for me was to export the line that does the exception to some other static function. I called it compareDates.

My implementation:

In the class that is tested (e.g - MyClass)
static boolean compareDates(Date date1, Date date2) { return DateUtils.isEqualByDateTime (date1, date2); }

and in the test class:
PowerMockito.mockStatic(MyClass.class); PowerMockito.when(MyClass.compareDates(any(Date.class), any(Date.class))).thenReturn(false);

Unfortunately I can't say I fully understand why this solution works and the previous didn't.
maybe it has to do with the fact that DateUtils class is not my code, and I can't access it's source, only the generated .class file, but i'm really not sure about it.


EDIT

The above solution was just a workaround that did not solve the need to cover the DateUtils isEqualByDateTime call in the code.
What actually solved the real problem was to import the DateUtils class which has the actual implementation and not the one that just extends it, which was what I imported before.

After doing this I could use the original line

PowerMockito.mockStatic(DateUtils.class);      

PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);

without any exception.

Achi Even-dar
  • 427
  • 1
  • 10
  • 20
0

I had a similar problem with TextUtils in my Kotlin Test Class

PowerMockito.`when`(TextUtils.isEmpty(Mockito.anyString())).thenReturn(true)

Resolved it by adding below code on top of my Test Class

 @PrepareForTest(TextUtils::class)

and called mockStatic this before PowerMockito.`when`

PowerMockito.mockStatic(TextUtils::class.java)