Mocking/Spying an abstract class

4,327 views
Skip to first unread message

Karl Schaefer

unread,
Nov 13, 2008, 4:20:44 PM11/13/08
to moc...@googlegroups.com
I have an abstract class that I want to mock, but I want the
non-abstract methods to be called. mock doesn't call any real methods
and I cannot spy a mock. How can I test the implementation of the
concrete members of an abstract class without manually creating a
subclass?

Below is my JUnit that describes the problem in code.

Thanks,

Karl

-----
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import org.junit.Test;

/**
* How do you mock an abstract class and still call the real code for
the non-abstract methods?
*/
public class MockitoTest {
public static abstract class Failure {
private Displayer d;

public void addDisplayer(Displayer d) {
this.d = d;
}

public void log(String s) {
d.display(s);
}
}

public interface Displayer {
void display(String s);
}

/**
* mock() fails to call real code.
*/
@Test
public void testMock() {
Failure f = mock(Failure.class);
Displayer d = mock(Displayer.class);

f.addDisplayer(d);
f.log("Some text.");

verify(d).display("Some text.");
}

/**
* cannot spy() a mock().
*/
@Test
public void testSpy() {
Failure f = spy(mock(Failure.class));
Displayer d = mock(Displayer.class);

f.addDisplayer(d);
f.log("Some text.");

verify(d).display("Some text.");
}
}

Igor Czechowski

unread,
Nov 14, 2008, 4:54:28 AM11/14/08
to moc...@googlegroups.com
Hi Karl,

You cannot.
Mockito doesn't support partial mocking and the best option is to
create the subclass.

What's wrong with subclass ?

Cheers,
Igor

Karl Schaefer

unread,
Nov 14, 2008, 8:25:55 AM11/14/08
to moc...@googlegroups.com
> You cannot.
> Mockito doesn't support partial mocking and the best option is to
> create the subclass.

Ok. Thanks, just wanted to be sure that I wasn't missing something.

> What's wrong with subclass ?

Nothing, I guess, but I didn't want to pollute the repository with a
dummy class containing no-ops. I want to test the functionality of
the abstract versus the children, as it is not possible to make all
methods final and it's important to ensure the correct functioning of
each method.

Karl

Dan North

unread,
Nov 14, 2008, 12:07:43 PM11/14/08
to moc...@googlegroups.com
Hi Karl

2008/11/14 Karl Schaefer <karlgs...@gmail.com>


> You cannot.
> Mockito doesn't support partial mocking and the best option is to
> create the subclass.

Ok.  Thanks, just wanted to be sure that I wasn't missing something.

> What's wrong with subclass ?

Nothing, I guess, but I didn't want to pollute the repository with a
dummy class containing no-ops.

When I want one of these for a specific test or tests I often just make it a static inner class or in the test case or package visible. That way its scope and purpose are more obvious.
 
I want to test the functionality of
the abstract versus the children,

Sounds to me like you could try composition rather than inheritance here. Make the abstract class a separate helper class in its own right, and pass in the "child" as a method parameter instead of having the helper call abstract methods.

as it is not possible to make all
methods final and it's important to ensure the correct functioning of
each method.

Yes, but correct functioning is different from correct implementation. If you are trying to ensure a particular abstract method is being called you are probably coupling your tests too tightly to your code.

Karl

Cheers,
Dan
Reply all
Reply to author
Forward
0 new messages