Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mocking method an interface inherits from its parent interface is not working when the method is re-stated in extending interface #305

Closed
ryanluedders opened this issue Oct 19, 2015 · 3 comments
Assignees
Labels

Comments

@ryanluedders
Copy link

I was trying to build a function that can return a mock of any interface extending a generic parent interface. The extending interface specifies the generic parameters.

I've found that if the extending interface does not re-declare the method, then it works as expected (the mock object exhibits mocked behavior when the method is invoked.)

If the extending interface does re-declare the method, then the mock object does not exhibit the mocked behavior when the method is invoked on the mock.

Hopefully the example below helps clarify:

package mockitotest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.mockito.Mockito;

// Test case demonstrating a perceived defect in Mockito
public class MockBuilderTest {

    // 1. Create an object to use for a return type
    public class ReturnType {

        String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

    // 2. Define an interface
    public interface OriginalInterface<N,O> {

        // contains a templated method
        O doSomething(N n);

    };

    // 3. Create an extending interface which specifies the templated arguments
    public interface ExtendingInterfaceObject extends OriginalInterface<String, ReturnType> {

        // 4. The method would be inherited, but I re-state it, mostly to add additional
        //      documentation inside the interface
        @Override
        ReturnType doSomething(String n);

    };

    // 5. For demonstration purposes, create an extending interface which does specify the
    //      templated arguments, but does not re-state the method
    public interface ExtendingInterfaceObjectNoRedef extends OriginalInterface<String, ReturnType> {}

    // A function to build a mocked object, the type of object is specified as a method argument
    // the value that should be returned (O) is also provided as an argument
    <N,O,T extends OriginalInterface<N,O>> T buildMock(Class<T> cls, final O o) {
        Class<N> n = null;

        // create a mocked object of the specified class
        T t = Mockito.mock(cls, Mockito.withSettings().verboseLogging());

        // override the doSomething function to return the desired value
        Mockito.when(t.doSomething(Mockito.any(n))).thenReturn(o);
        return t;
    }

    // Example A: I would expect that 'r' be returned by the resulting mocked object, but
    //      mockito doesn't seem to match up the invocation with an overriden method
    @Test
    public void testBuild_object() {
        ReturnType r = new ReturnType();
        r.setName("testBuild");

        ExtendingInterfaceObject i = buildMock(ExtendingInterfaceObject.class, r);

        assertTrue(i instanceof ExtendingInterfaceObject);
        assertEquals(r, i.doSomething("TEST"));
    }

    // Example B: like example A, but this uses the extending interface which *does not*
    //      re-state the method. This example completes successfully.
    @Test
    public void testBuild_object_no_redef() {
        ReturnType r = new ReturnType();
        r.setName("testBuild");

        ExtendingInterfaceObjectNoRedef i = buildMock(ExtendingInterfaceObjectNoRedef.class, r);

        assertTrue(i instanceof ExtendingInterfaceObjectNoRedef);
        assertEquals(r, i.doSomething("TEST"));
    }

}
@raphw
Copy link
Member

raphw commented Oct 19, 2015

I think that you are suffering the same condition as #304

The method is intercepted appropriately but the bridge is currently not resolved by Mockito.

@ryanluedders
Copy link
Author

Thanks, you're probably right. I can keep an eye on that one too.

@raphw raphw added the bug label Nov 10, 2015
@raphw raphw self-assigned this Nov 10, 2015
@raphw
Copy link
Member

raphw commented Nov 10, 2015

Closed as duplicate of another open issue. (#304)

@raphw raphw closed this as completed Nov 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants