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

Capturing interfaces fails because of parameter order #20

Closed
nsinkov opened this Issue Jul 30, 2014 · 2 comments

Comments

2 participants
@nsinkov

nsinkov commented Jul 30, 2014

I have two interfaces and I am mocking one method on each one. I'm using the @Capturing annotation. But simply having the @Mocked parameters in a different order causes one of the interfaces to not be mocked.

(The same happens if the @Mocked parameters are fields of the test class - the order matters)

The code below has two identical tests. One fails only because the parameters are in a different order. (I believe that both tests should pass)

code:

import mockit.Capturing;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import mockit.integration.junit4.JMockit;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JMockit.class)
public class InterfaceMocks {

public static interface I1 {
    Double num();
    String other();
}

public static interface I2 {
    I1 getI1();
    String method();
}

@Test
public void testGood(@Mocked("num") @Capturing final I1 i1Mock, @Mocked("getI1") @Capturing final I2 i2Mock) {
    new NonStrictExpectations() {
        {
            i1Mock.num();
            result = null;

            i2Mock.getI1();
            result = null;
        }
    };

    I2 i2 = new I2() {
        @Override
        public I1 getI1() {
            throw new RuntimeException();
        }

        @Override
        public String method() {
            throw new RuntimeException();
        }
    };

    I1 i1 = i2.getI1();

}

@Test
public void testBad(@Mocked("getI1") @Capturing final I2 i2Mock, @Mocked("num") @Capturing final I1 i1Mock) {
    new NonStrictExpectations() {
        {
            i1Mock.num();
            result = null;

            i2Mock.getI1();
            result = null;
        }
    };

    I2 i2 = new I2() {
        @Override
        public I1 getI1() {
            throw new RuntimeException();
        }

        @Override
        public String method() {
            throw new RuntimeException();
        }
    };

    I1 i1 = i2.getI1();

}

}

@rliesenfeld rliesenfeld self-assigned this Jul 30, 2014

@rliesenfeld rliesenfeld added the bug label Jul 30, 2014

@rliesenfeld

This comment has been minimized.

Show comment
Hide comment
@rliesenfeld

rliesenfeld Jul 30, 2014

Member

Yes, seems like there is a subtle bug here; I will look into it.

Two details in the example tests catch the attention, though; if you can clarify I would appreciate:

  1. Why the partial mocking with @Mocked("num"), etc.? Does the (real) test actually need to execute the real code of some methods, while others are mocked?
  2. null is the default result for any method returning a reference type, so recording "result = null" for them is redundant. Or is there something I missed?
Member

rliesenfeld commented Jul 30, 2014

Yes, seems like there is a subtle bug here; I will look into it.

Two details in the example tests catch the attention, though; if you can clarify I would appreciate:

  1. Why the partial mocking with @Mocked("num"), etc.? Does the (real) test actually need to execute the real code of some methods, while others are mocked?
  2. null is the default result for any method returning a reference type, so recording "result = null" for them is redundant. Or is there something I missed?
@nsinkov

This comment has been minimized.

Show comment
Hide comment
@nsinkov

nsinkov Jul 30, 2014

"Does the (real) test actually need to execute the real code of some methods, while others are mocked?"
correct

"null is the default result for any method returning a reference type, so recording "result = null" for them is redundant. Or is there something I missed?"
yeah, that's just for this test code - not null in the real code

nsinkov commented Jul 30, 2014

"Does the (real) test actually need to execute the real code of some methods, while others are mocked?"
correct

"null is the default result for any method returning a reference type, so recording "result = null" for them is redundant. Or is there something I missed?"
yeah, that's just for this test code - not null in the real code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment