stubing protected methods?

9,834 views
Skip to first unread message

Max

unread,
Jun 1, 2010, 3:48:13 AM6/1/10
to moc...@googlegroups.com
I read an article about Mockito's spy objects. The author of the article claims he was able to stub protected methods here's a quote,

"when(rule.createFileTemplate()).thenReturn(mockFileTemplate);

Exactly the syntax I wanted! And it works for public AND protected methods, wether the method is called from the outside or the inside of the spied object."

But I get compilation errors when I try to do it.

Here's link to that aritcle: http://blog.javabien.net/2009/06/21/mockitos-partial-mocks-testing-real-objects-just-got-easier/

Max.

Kristofer Karlsson

unread,
Jun 1, 2010, 4:15:34 AM6/1/10
to moc...@googlegroups.com
Is your test code in the same package as the rule class?
Otherwise you can't use protected.

--
You received this message because you are subscribed to the Google Groups "mockito" group.
To post to this group, send email to moc...@googlegroups.com.
To unsubscribe from this group, send email to mockito+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mockito?hl=en.

Max

unread,
Jun 1, 2010, 4:35:03 AM6/1/10
to moc...@googlegroups.com
No, it's in a different package, I don't see why one would keep their tests in the same package. I would've thought mockito does something fancy to increase the visibility of protected methods but I guess I need to write my own stub to expose it.

Thanks for your input! ;)

Max.

Kristofer Karlsson

unread,
Jun 1, 2010, 4:52:17 AM6/1/10
to moc...@googlegroups.com
Mockito can't modify the java rules for visibility - protected methods can only be seen by classes in the same package and classes that extend the class. This is resolved at compile time, not at runtime, so Mockito can't possible fix it for you.

Max

unread,
Jun 1, 2010, 5:12:47 AM6/1/10
to moc...@googlegroups.com
What about Reflection?

Max.

Kristofer Karlsson

unread,
Jun 1, 2010, 5:19:16 AM6/1/10
to moc...@googlegroups.com
Reflection can't help you solve compilation errors.

Maciej Biłas

unread,
Jun 1, 2010, 5:33:47 AM6/1/10
to moc...@googlegroups.com
Please mind that Mockito uses statically checked Java code. Where
exactly do you think it uses reflection?

mock.yourMethod() doesn't look like a reflected method invocation to
me. Don't you think?

m.

On Tue, Jun 1, 2010 at 11:12 AM, Max <maxo...@gmail.com> wrote:

--
Maciej Biłas

Max

unread,
Jun 1, 2010, 7:43:21 AM6/1/10
to moc...@googlegroups.com
You're right it doesn't and it won't solve compilation errors for mock.method() approach. I guess I meant to say I would've hoped it used something like reflection for protected or even private methods. It uses reflection internally anyway. Why no introduce something like,

when(mock).invoke("privateMethod").thenReturn("something")

I mean it's not very consistent with the rest of api but it would make life a hell of alot easier when testing legacy code and where deadlines are too short for refactoring. ;)

James Carr

unread,
Jun 1, 2010, 8:32:57 AM6/1/10
to moc...@googlegroups.com
When stubbing spies it is best to use the alternative method for stubbing:

doReturn("foo").when(rule).createFileTemplate();

or

willReturn("foo").given(rule).createFileTemplate();

Because otherwise the real method will be called and may cause your
test to blow up.


Thanks,
James

James Carr

unread,
Jun 1, 2010, 8:34:19 AM6/1/10
to moc...@googlegroups.com
I say no... you should never test private methods and if it is legacy
code you should just make the thing public so that it sticks out like
a sore thumb that it needs to be extracted. Allowing people to get
away with stubbing private methods just opens the door for cheating
and poorly designed code.

Thanks,
James

Max

unread,
Jun 1, 2010, 8:46:58 AM6/1/10
to moc...@googlegroups.com
@James, I like your attitude! I wish you were my tech lead.

Johan Haleby

unread,
Jun 2, 2010, 5:07:32 AM6/2/10
to moc...@googlegroups.com
PowerMock let's you stub/mock private methods if you really need to. But you should listen to what people say here before you start using it because usually there are better solutions available.

/Johan

Jose Donizetti

unread,
Jun 2, 2010, 5:40:27 AM6/2/10
to moc...@googlegroups.com
Sorry, about going with this off-topic.

But Max, why can't you just put your test on the same package? Doing
that, you will have the ability to test your protected method, and
your code will stay better organized, for you or others to find the
test in a future.
When I mean the same package, i mean in a different source folder! =D

James Carr

unread,
Jun 2, 2010, 8:18:09 AM6/2/10
to moc...@googlegroups.com
A practice do is I often put my tests in a test package (i.e.
org.jamescarr.something.test) to ensure that a backdoor isn't opened
for testing. :)

Thanks,
James

szczepiq

unread,
Jun 2, 2010, 8:38:23 AM6/2/10
to moc...@googlegroups.com
>I often put my tests in a test package (i.e.
>org.jamescarr.something.test) to ensure that a backdoor isn't opened
>for testing. :)

Really? I often put my tests in the same package to ensure that backdoor is opened for testing :)

Cheers,
Szczepan

James Carr

unread,
Jun 2, 2010, 9:12:57 AM6/2/10
to moc...@googlegroups.com
it depends... I make exceptions if the class is package scoped,
otherwise I try to test drive my code through the public interface as
often as possible, extracting new collaborators when I find myself
tempted to test or stub out protected methods. ;)

Thanks,
James

Michael Hackett

unread,
Jun 2, 2010, 4:41:39 PM6/2/10
to moc...@googlegroups.com
That's what I do too, James: tests in a .test package, drive the code-under-test through its public API. An exception might be legacy code that I'm not ready to break apart yet, but the fact that the test code is not in a test package is a reminder to come back and fix the problem properly.

I've only been using this approach for a year or so, since coming back onto a Java project, but it's working well so far.

Jose Donizetti

unread,
Jun 2, 2010, 8:12:20 PM6/2/10
to moc...@googlegroups.com
What I do is put my tests at the same packages but in a differents
source folder. But I do always drive my code by tests testing so I end
up testing only the public api, some really rare exceptions I do put
my method scope to package('default'). But the role is public for
methods drived by the tests and private for everything else.

Reply all
Reply to author
Forward
0 new messages