开发者

How to isolate other methods in the same class using EasyMock

I have a method that invokes other method in the same class such as:

Class MyClass{
   public int methodA(){
      ...
      methodB()
      ...
   }

   public int methodB(){
      ...
   }
}

And I just wanna test methodA(), so how can I isolate methodB() using EasyMock. My damn way is t开发者_如何转开发o create a fake instance of MyClass and inject it into the methodA() like this:

public int methodA(MyClass fake){
   ...
   fake.methodB();
   ...
}

and expect it in my testcase:

MyClass fake = EasyMock.createMock(MyClass.class);    
EasyMock.expect(fake.methodB()).andReturn(...);

Is there any better solution for this situation?


Yes: Don't use EasyMock but an anonymous local class. Example:

public void testXyz throws Exception() {
    MyClass fake = new MyClass() {
        public int methodB(){
            return 12;
        }
    };

    fake.methodA();
}


well...it is so simple :-)

YourClass instance = mock(YourClass.class);

when(instance.methodB(args)).thenReturn(aFakeAnswer);
when(instance.methodA(args)).thenCallRealMethod();

I'm sorry for not exact code but in general it does it work like that and you can unit test abstract classes as well using this.


Here's a surprisingly simple solution using EasyMock. It looks daunting but is actually a very simple concept.

The trick is to create in your test class both a regular MyClass object and a mocked MyClass object. Then when you instantiate the regular MyClass, override the method that you want to mock out and have it call the same method in the mocked MyClass.

Given this class:

Class MyClass{
    public int methodA(){
        ...
        methodB()
        ...
    }

    public int methodB(){
        ...
    } 
}

In your test write:

Class MyClassTest {

    private MyClass myClass;
    private MyClass mockMyClass;
    ...

    @Test
    public void testMethodA() {
        // Create mock of MyClass
        mockMyClass = createMock(MyClass.class);

        // Instantiate MyClass overriding desired methods with mocked methods
        myClass = new MyClass() {
            @Override
            public int methodB() {
                return mockMyClass.methodB();
            }
        };

        // Set expectations
        expect(mockMyClass.methodB()).andReturn(...);
        replay(mockMyClass);

        // Call test method - will in turn call overridden, mocked methodB()
        myClass.methodA();

        verify(mockMyClass);
    }

}

You may want to have helper methods that instantiate myClass differently depending on what method you are testing.


I think you should consider refactoring MyClass.
If the both methods use the same logic in methodB() then extracting the logic to a private method will enable you to test for the isolated scenario of calling each of these methods.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜