user86834
user86834

Reputation: 5645

Mock Spring's MessageSource.getMessage method

I'm trying to mock Spring's MessageSource.getMessage method but Mockito it is complaining with an unhelpful message, I am using:

when(mockMessageSource.getMessage(anyString(), any(Object[].class), any(Locale.class)))
    .thenReturn(anyString());

The error message is:

You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:

when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());

verify(mock).someMethod(contains("foo"))

Also, this error might show up because you use argument matchers with methods 
that cannot be mocked Following methods *cannot* be stubbed/verified: final/private/equals()
/hashCode().

Any idea what I am doing wrong?

Upvotes: 5

Views: 14758

Answers (7)

Arun Kumar T
Arun Kumar T

Reputation: 66

Mockito.when(messageSource.getMessage(Mockito.anyString(), Mockito.any(),Mockito.any(Locale.class))).thenReturn("Error Message");

this will help you

Upvotes: 1

Ming Zhu
Ming Zhu

Reputation: 282

getMessage method on class ResourceBundleMessageSource is final

Upvotes: 1

mrkernelpanic
mrkernelpanic

Reputation: 4471

I solved this issue by only spying the MessageSource (so I still can verify the getMessage call later) and setting the flag 'useCodeAsDefaultMessage' to true. In this case a fallback mechanism from the AbstractMessageSource#getMessage will do its job and just return the supplied key as message.

messageSource = spy(new ReloadableResourceBundleMessageSource());
messageSource.setUseCodeAsDefaultMessage(true);

Upvotes: 1

herman
herman

Reputation: 12305

While the accepted answer has the fix for the code in the question, I'd like to note that it is not necessary to use a mock library just to create a MessageSource that always returns an empty string.

The following code does the same:

MessageSource messageSource = new AbstractMessageSource() {
    protected MessageFormat resolveCode(String code, Locale locale) {
        return new MessageFormat("");
    }
};

Upvotes: 6

Aidan O
Aidan O

Reputation: 549

The issue here is that you need to return some actual object matching the return type of the method from your mock. Compare with:

when(mockMessageSource.getMessage(anyString(), any(Object[].class), any(Locale.class))).
thenReturn("A Value that I care about, or not");

The larger issue this points to is that you're really not testing any behavior. You might want to consider what value this test is providing. Why mock the object in the first place?

Upvotes: 1

Christian Kuetbach
Christian Kuetbach

Reputation: 16060

Well, one thing looks strange to me:

You are returning Mockito.anyString() this is a Matcher.

I think you must return a concrete String.

when(mockMessageSource.getMessage(anyString(), any(Object[].class), any(Locale.class)))
.thenReturn("returnValue");

Upvotes: 3

MattSenter
MattSenter

Reputation: 3120

The problem, I believe, is that anyString() is the matcher it is complaining about when it is used as a parameter in your thenReturn(...) call. If you don't care what's returned, just return an empty String a la thenReturn("").

Upvotes: 4

Related Questions