History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: UNI-168
Type: Bug Bug
Status: Closed Closed
Resolution: Cannot Reproduce
Priority: Major Major
Assignee: Tim Ducheyne
Reporter: James Davis
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Unitils

Mocks to not behave correctly when they are cast to a parent of the class they mock.

Created: 22/Sep/09 03:27 PM   Updated: 29/Sep/09 02:27 AM
Component/s: mock
Affects Version/s: 2.4
Fix Version/s: 3.0

Environment: Eclipse 3.5, JUnit 4, java 1.6


 Description  « Hide
I have a class that extends java.util.TimerTask. When trying to pass a mock of that class into my test class, the java.util.Timer class throws an NPE.

This appears to be because you cannot cast the mock to the base class of the class it mocks.

Here is kind of a simple testCase.... (not be fully syntactically correct, but should be enough to understand how to repro).

public class ClassToMock extends java.util.TimerTask
{}

private Mock<ClassToMock> mockClass;

@Test
public void TestMockClass()
{
    assertNotNull("Ooops..", (TimerTask) mockClass.getMock());
}

This will fail because the mock cannot be cast the base class of the object. As I understand it, this breaks a fundamental principal of polymorphism as well as defeats part of the purpose for use of mock objects. I understand that this is likely do to the proxies generated by CGLIB, but it would be nice if this was fixed.

 All   Comments   Change History      Sort Order:
James Davis - 23/Sep/09 05:30 AM
I was doing a little bit of looking around today, and it looks like this may be a common issue with mocking frameworks. I've seen a few .NET ones that have found some ways around this (RhinoMock is one of them).

The way they have solved it is to create a mock that can mock multiple interfaces or classes.

I'm not sure how something like that would look with unitils, but I do believe it would make a good addition.

Tim Ducheyne - 28/Sep/09 06:22 PM
Hi James,

I'm not sure what is causing the NullPointer but I don't think the casting is the problem. I've tried executing following test:

public class MockObjectCastTest extends UnitilsJUnit4 {

    private Mock<ClassToMock> mockClass;


    @Test
    public void testCasting() {
        assertNotNull("Ooops..", (TimerTask) mockClass.getMock());
    }


    public class ClassToMock extends TimerTask {
        public void run() {
        }
    }

}


This test is succesful, so the casting seems to work.
Are you sure that the mocks are being created? I think mockClass.getMock() is giving the NullPointerException.
Did you extend from a unitils base class, e.g. extends UnitilsJUnit4
By extending this base class, unitils will be able to create and inject the mocks during the test
Note: you can also create mocks programmatically:
 Mock<ClassToMock> mockClass = new MockObject<ClassToMock>("mockName', ClassToMock.class, this);

grtz,
Tim

James Davis - 29/Sep/09 02:27 AM
Ok, after a little bit more poking around, I think I figured out what's going on...

What was throwing the NPR was a lock object in the TimerTask being null. Looking at the code, it should be initialized when the object is instantiated, but isn't.

So, this ties back into another bug I opened a while ago about the mocks not calling the constructors correctly.