How do you mock this?

1,394 views
Skip to first unread message

SkullCruncha

unread,
Feb 28, 2008, 12:45:56 AM2/28/08
to mockito
public class StaticFacade
{
public static boolean staticMethod()
{
return true;
}
}

public class AppMediator
{

public boolean getDataThroughStaticFacade()
{
return StaticFacade.staticMethod();
}
}

public class AppMediatorTest
{
@Test
public void test_getDataThroughStaticFacade()
{
assertTrue("Expected true.",
_AppMediator.getDataThroughStaticFacade());

verify(StaticFacade).staticMethod();
}
}

I'm presuming this is impossible, but I thought I'd ask....

szczepiq

unread,
Feb 28, 2008, 6:35:29 AM2/28/08
to moc...@googlegroups.com
Hi,

Mockito doesn't mock static methods to promote OO design and dependency injection :)

If you need to mock static call - you can refactor it to be an instance method, a decent citizen of OO world.

If you work with legacy/closed code that you cannot refactor, you can wrap statics with a class. Then you can easily mock it/inject it.

If you really, *really* need to mock statics (e.g. immersed in horrible legacy madness) you can use JMockit - a library to mock 'unmockables'

The choice is yours!

There were other people who asked for mocking statics. Tell us what you think. Is this a feature you want from Mockito?

Cheers,
Szczepan Faber

SkullCruncha

unread,
Feb 28, 2008, 1:38:59 PM2/28/08
to mockito
For now I would leave that out of the framework. I agree with you
dependency injection is the appropriate counter.

A thought though - in the google code listing (/p/mockito) in the
section of "Limitations", I might add a static method comment.

FYI, I have now used mockito in production code - in a place I would
have never mocked before - UI code. That I can mock concrete framework
classes is absolutely wonderful.

szczepiq

unread,
Feb 28, 2008, 2:58:08 PM2/28/08
to moc...@googlegroups.com
>A thought though - in the google code listing (/p/mockito) in the
>section of "Limitations", I might add a static method comment.

Ok, I'll look at it.


>FYI, I have now used mockito in production code - in a place I would
>have never mocked before - UI code. That I can mock concrete framework
>classes is absolutely wonderful.

Good to hear that!

Cheers,
Szczepan Faber

Bartosz Bankowski

unread,
Feb 29, 2008, 11:11:34 AM2/29/08
to mockito
What about such a case:

class DateUtil {
public static long getCurrentTimestamp() {
return System.currentTimeMillis();
}
}

class MyClass {
public void myMethod() {
(...)
long timestamp = DateUtil.getCurrentTimestamp();
(...)
}
}

I don't like injecting that kind of classes. They are usually very
simple and there will be only one implementation. For me refactoring
it towards DI doesn't introduce any value and adds unnecessary code. I
won't refactor it only because I need to write a test for it (don't
get me wrong here; I always refactor legacy code to tests, but it
should result in improved design also).

I definitely want this feature in Mockito!

Regards,
Bartosz Bankowski

szczepiq

unread,
Mar 1, 2008, 4:57:51 AM3/1/08
to moc...@googlegroups.com
>I definitely want this feature in Mockito!

Hold on... You want this feature to mock System.currentTimeInMillis() ?

I'm not convinced. I've never had to mock static methods like Math.min() or Arrays.asList() or IOUtils.readLines(), ... For me, this is almost a part of a language.

Current time is often problematic in testing. In typical java app I usually go for time freeze pattern, e.g: Clock.freeze() in setup, Clock.unfreeze() in teardown. Simple & cheap. In apps where multi-threading is essential (e.g: taking advantage on modern CPUs) I would lean towards injectable time service... But I guess you can get away with ThreadLocal... It's up to you, just don't mock currentTimeInMillis() :)

Cheers,
Szczepan Faber


Why would I want to mock System.currentTimeMillis() ? I mock methods that are too heavy, too complex.

Bartosz Bańkowski

unread,
Mar 1, 2008, 6:21:31 AM3/1/08
to moc...@googlegroups.com
Szczepan,

It was a simple example to show you my point of view. It is not only
about time, but other things also e.g. IO which you mentioned, random
numbers. I am not talking about mocking what you call part of a
language, but util classes which each of us develop as a part of our
systems. What is important it is about util classes which are
unpredictable or interfere with external systems, network etc. I will
never mock my implementation of Math.min() as I don't see any reason
to do it.

Regards,
Bartosz

szczepiq

unread,
Mar 1, 2008, 10:08:43 AM3/1/08
to moc...@googlegroups.com
Ok then, we're waiting for a case where you had to mock static method. Show us a *real* example (I don't believe that mocking currentTimeInMillis() is a good idea).

Being too powerful may be dangerous for a tool like Mockito. After all, we all agree that if something is difficult to test it's not the test tool to blame. The unit (for example  a class) under test is guilty. 

Cheers,
Szczepan Faber

PS.
Problem of mocking static methods in scary legacy systems is already solved: see JMockit.

Bartosz Bańkowski

unread,
Mar 3, 2008, 8:28:23 AM3/3/08
to moc...@googlegroups.com
Still, I am not talking about legacy systems. I would not use JMockit
in legacy to mock statics. I'd rather create a set of high-level tests
(integration, functional etc.) and refactor mercilessly :) It is only
about those util classes, which I mentioned in previous mail. If you
don't like date/time example, than maybe something like that would be
more expressive:

public class DbUtil {

(...)

public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException ex) {
LOG.debug("Some message");
}
}
}
}

Now, I prefer code like the one below and I don't consider the class
guilty for not begin able to write a test for it:

public class MyClass {
public void doSomething() {
Connection conn = getConnection();
// perform some db operations
DbUtil.close(conn);
}
}

I can inject DbUtil, but is it really a good practice for such a class?

public class MyClass {
private DbUtil dbUtil;

public MyClass(DbUtil dbUtil) {
this.dbUtil = dbUtil;
}

public void doSomething() {
Connection conn = getConnection();
// perform some db operations
dbUtil.close(conn);
}
}

The other solution would be to extract method with close and override
it in the test. But it also doesn't look good to me.

I know that when begin too powerful people can use Mockito not how it
was intended to be used.

Regards,
Bartosz

2008/3/1 szczepiq <szcz...@gmail.com>:

szczepiq

unread,
Mar 3, 2008, 11:25:48 AM3/3/08
to moc...@googlegroups.com
I feel uneasy about this DbUtil.close()

close(Connection c) method belongs to the same object that has getConnection() method. Is getConnection() also a static on DbUtils?

It's easy to forget about close(). Closeable is coming with JDK7 (hopefully). Until then I'd go for some kind of interface, like:

interface LetMePlayWithDb {
   void play(Connection connection);
}

and then a public method for clients:

public void playWithDb(LetMePlayWithConnection letMe) {
   try {
      letMe.play(connection);
   }
   ... put close / cleanup / rethrow here
}

Instead of playing with connection directly, the developer implements LetMePlayWithDb...

I know I should talk about mocks but this whole BbUtils.close() smells funny...

Cheers,
Szczepan Faber

2008/3/3 Bartosz Bańkowski <bbank...@gmail.com>:

felix leipold

unread,
Mar 3, 2008, 1:54:51 PM3/3/08
to mockito
Hi Bartosz,

another thing that seems quite odd to me. You want to mock the
DBUtils, but what about the connection, is it also mocked out?
You will have to provide it anyway, so why not:

1. Call real dbutils methods on a mock connection?
Or
2. Wrap the connection into your own connection class that hides all
the ugly exception handling code and can be mocked out more easily?

Hope this helps,

felix

On Mar 3, 4:25 pm, szczepiq <szcze...@gmail.com> wrote:
> I feel uneasy about this DbUtil.close()
>
> close(Connection c) method belongs to the same object that has
> getConnection() method. Is getConnection() also a static on DbUtils?
>
> It's easy to forget about close(). Closeable is coming with JDK7
> (hopefully). Until then I'd go for some kind of interface, like:
>
> interface LetMePlayWithDb {
> void play(Connection connection);
>
> }
>
> and then a public method for clients:
>
> public void playWithDb(LetMePlayWithConnection letMe) {
> try {
> letMe.play(connection);
> }
> ... put close / cleanup / rethrow here
>
> }
>
> Instead of playing with connection directly, the developer implements
> LetMePlayWithDb...
>
> I know I should talk about mocks but this whole BbUtils.close() smells
> funny...
>
> Cheers,
> Szczepan Faber
>
> 2008/3/3 Bartosz Bańkowski <bbankow...@gmail.com>:
> > 2008/3/1 szczepiq <szcze...@gmail.com>:
> > > Ok then, we're waiting for a case where you had to mock static method.
> > Show
> > > us a *real* example (I don't believe that mocking currentTimeInMillis()
> > is a
> > > good idea).
>
> > > Being too powerful may be dangerous for a tool like Mockito. After all,
> > we
> > > all agree that if something is difficult to test it's not the test tool
> > to
> > > blame. The unit (for example a class) under test is guilty.
>
> > > Cheers,
> > > Szczepan Faber
>
> > > PS.
> > > Problem of mocking static methods in scary legacy systems is already
> > solved:
> > > see JMockit.
>
> > > On Sat, Mar 1, 2008 at 11:21 AM, Bartosz Bańkowski <bbankow...@gmail.com
>
> > > wrote:
>
> > > > Szczepan,
>
> > > > It was a simple example to show you my point of view. It is not only
> > > > about time, but other things also e.g. IO which you mentioned, random
> > > > numbers. I am not talking about mocking what you call part of a
> > > > language, but util classes which each of us develop as a part of our
> > > > systems. What is important it is about util classes which are
> > > > unpredictable or interfere with external systems, network etc. I will
> > > > never mock my implementation of Math.min() as I don't see any reason
> > > > to do it.
>
> > > > Regards,
> > > > Bartosz
>
> > > <bbankow...@gmail.com>

Bartosz Bańkowski

unread,
Mar 3, 2008, 2:19:23 PM3/3/08
to moc...@googlegroups.com
Felix,

You are right. In the real life application connection is mocked, so
reference to DbUtil is not impacting the test. I guess I should be
more careful when sending code snippets here. The proper example of
the situation I am trying to explain in this thread should not have
any argument in the static method which is called, so that it can't be
mocked.

Regards,
Bartosz

2008/3/3 felix leipold <felix....@googlemail.com>:

Reply all
Reply to author
Forward
0 new messages