jmockit / jmockit1

Advanced Java library for integration testing, mocking, faking, and code coverage
Other
465 stars 240 forks source link

Dynamic Partail Mocking is cascading when I provide an actual result object #90

Closed djrichar closed 10 years ago

djrichar commented 10 years ago

The Tutorial document state:

If necessary, this default mocked instance can be replaced with a non-mocked one or with a different mocked instance; for that, simply assign the desired instance to the result field in a recorded expectation.

so given the sample test below i would expect the 2nd test to pass however it fails

package mockit;

import org.junit.Assert;
import org.junit.Test;

import java.util.Date;
import java.util.List;

/**
 * dynamic partial mocking causes cascading to return improper result object.  
 * according to documentation my interpretation is that if i provide the result object then that object should not be cascaded.
 */
public class CascadingWithDynamicMocking {

    static class Foo
    {
        Bar getBar() { return null; }

        static Bar globalBar() { return null; }

        void doSomething(String s) { throw new RuntimeException(s); }
        int getIntValue() { return 1; }
        private Boolean getBooleanValue() { return true; }
        String getStringValue() { return "abc"; }
        public final Date getDate() { return null; }
        final List<Integer> getList() { return null; }

    }

    static class Bar
    {
        Bar() {}
        int doSomething() { return 1; }
        boolean isDone() { return false; }
        Short getShort() { return 1; }
        List<?> getList() { return null; }
        Baz getBaz() { return null; }
        Runnable getTask() { return null; }
        String getStringValue() {return "Bar";}
    }

    static final class Baz { void doSomething() {}
        public String getStringValue(){return "Baz";}
    }

    @Test  //Successful
    public void cascadingWithPartialMocking(){
        new Expectations(Foo.class){
            {
                Foo.globalBar();
            }
        };

        Bar actual = Foo.globalBar();
        Assert.assertNotNull(actual);
        Assert.assertNotNull(actual.getBaz());
        Assert.assertNull(actual.getBaz().getStringValue());
    }

    @Test  //Failure 
    public void cascadingWithPartialMockingWithResult(){
        final Bar expectedBar = new Bar();
        Assert.assertEquals("Baz", expectedBar.getBaz());

        new Expectations(Foo.class){
            {
                Foo.globalBar(); result = expectedBar;
            }
        };

        Bar actual = Foo.globalBar();
        Assert.assertNotNull(actual);
        Assert.assertNotNull(actual.getBaz());
        Assert.assertSame(expectedBar, actual.getBaz());
        Assert.assertEquals("Baz", actual.getBaz().getStringValue());  //expected Baz but got null
    }
}
rliesenfeld commented 10 years ago

Please review the example test class, because it got errors. That first assertion in the second test, for one, can never pass.

With a fixed and simplified version of the second test, I don't see any problem, it passes:

@Test
public void cascadingWithPartialMockingWithResult() {
    final Bar expectedBar = new Bar();

    new Expectations(Foo.class) {{
        Foo.globalBar(); result = expectedBar;
    }};

    Bar actual = Foo.globalBar();
    Assert.assertSame(expectedBar, actual);
}