funbee / mockito

Automatically exported from code.google.com/p/mockito
0 stars 0 forks source link

custom agument matcher called to match wrong method call #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I had a custom argument matcher defined to verify a call to function X.
The custom argument matcher's match function was called when looking for an
argument matcher for function Y.

I am using Mockito 1.2

--

What steps will reproduce the problem?
2. setup a test that calls two functions, one taking a string parameter, 
the other taking a domain object
3. create a custom matcher that matches the domain object
4. verify the 2nd call only:

verify(view, atLeastOnce()).addProperty( argThat(new customDomainMatcher()) ); 

5.  the custom domain matcher will be called to validate the string
parameter, even though the verify is on the other function call

What is the expected output? What do you see instead?

The custom matcher should be called only on the particular function being
verified.

It is actually called for other functions too.

I think this is because in InvocationMatcher.java:

overloadedButSameArgs calculation calls the customer matcher defined for
method function X even though wantedMethodName and currentMethodName differ

In my case, a string is being passed by the call calculating
overloadedButSameArgs which can't be converted to the domain object and
fails.  It shouldn't be called in the first place, becuase if
methodNameEquals if false, nothing else should happen?

Solution:
return false immediately in InvocationMatcher.isSimilarTo if wanted and
current names differ.

The attached implementation of InvocationMatcher.isSimilarTo works for me.

What version of the product are you using? On what operating system?

Please provide any additional information below.

Original issue reported on code.google.com by kevin.da...@gmail.com on 13 Mar 2008 at 6:02

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks for detailed report, I'll take a look at it.

Original comment by iczechowski@gmail.com on 13 Mar 2008 at 10:33

GoogleCodeExporter commented 9 years ago

Original comment by szcze...@gmail.com on 16 Mar 2008 at 2:50

GoogleCodeExporter commented 9 years ago
Again, thank you very much for very detailed report and for suggesting the fix.

InvocationMatcher.isSimilarTo() method have no effect on verification. This 
method is
only used to decide what kind of verification message to print. E.g. at the 
point
when isSimilarTo() is called the verification has already failed.

I created a test case according to your description and everything works fine 
(can
you paste it to your IDE and tell me if this is it?):

{{{
    interface View {
        void addProperty(String property);
        void addProperty(DomainObject property);
    }

    class DomainObject {}

    class CustomDomainMatcher extends ArgumentMatcher<DomainObject> {
        @Override public boolean matches(Object argument) {
            return true;
        }
    }

    @Test
    public void testBug() throws Exception {
        View view = mock(View.class);

        view.addProperty(new DomainObject());
        view.addProperty("test");

        verify(view, atLeastOnce()).addProperty(argThat(new CustomDomainMatcher()));
        verify(view, times(1)).addProperty(argThat(new CustomDomainMatcher()));

        verify(view, atLeastOnce()).addProperty("test");
        verify(view, times(1)).addProperty("test");
    }
}}}

Misbehaviour in your code may be related to following:

Look at this line:

verify(view, atLeastOnce()).addProperty( argThat(new CustomDomainMatcher()) ); 

Given that addProperty() method is overloaded in your code, it is very 
important what
kind of generic type your customDomainMatcher is defined with:

class CustomDomainMatcher extends ArgumentMatcher<DomainObject> {

or 

class CustomDomainMatcher extends ArgumentMatcher<String> {

Compiler uses this generic type to determine which overloaded version of the 
method
to use.

If your matcher is not generic, you have to cast the argument to make compiler 
happy:
verify(view, atLeastOnce()).addProperty((DomainObject) argThat(new
customDomainMatcher()) ); 

Closing the bug - please reopen if it still doesn't work for you.

Original comment by szcze...@gmail.com on 16 Mar 2008 at 3:09

GoogleCodeExporter commented 9 years ago
It will be a few days, but I will give that a try in my environment. 
K

Original comment by kevin.da...@gmail.com on 24 Mar 2008 at 9:02

GoogleCodeExporter commented 9 years ago

Original comment by szcze...@gmail.com on 19 Apr 2009 at 7:40