« Return to Thread: mocking concrete classes with final toString method

Re: mocking concrete classes with final toString method

by Nat Pryce :: Rate this Message:

Reply to Author | View in Thread

2008/7/17 Haroon Rafique <haroon.rafique@...>:
> I have tests right now that use concrete mocks of classes which have final
> toString methods and they work fine in jmock1. E.g.:
>
>      service.expects(once())
>              .method("getReplyDB2Output")
>              .will(returnValue(pda));
>
> where service is a concrete class (not interface) with a final toString
> method. Did I mention it was a 3rd-party class?

What error message does jMock 1 generate if you use service as a
parameter constraint of a failing expectation or pass it as a
parameter of an invocation that causes an expectation to fail?

> So, now you can appreciate why I said that it looks like my only option is
> to stay with jmock1. Staying with jmock1 for ever doesn't sound very
> appealing to me. I know jmock1 and jmock2 are significantly different
> beasts but not having an upgrade path is a little tough to swallow.
>
> I don't know enough about jmock2 source but I'm willing to experiment
> with it if you or anyone else suggests some patches to try.

You can look into writing your own Imposteriser that can imposterise
concrete classes where toString is final.  An implementation would
work just for the scenario you have, and would not support all cases
and will produce confusing error messages in some cases, so cannot go
into jMock core.

However, the problem comes from mocking third-party code that you
cannot change.  It's not what we recommend jMock for because you
cannot change the code in response to the feedback jMock gives you
about its design. We recommend using mock objects to test code that
you have full control over: when you have written both the class and
it's outgoing interfaces.

When testing code that is using classes that I cannot change I write
an integration test that tests that the code I've written works as I
expect when integrated with code that I do not have full knowledge of.
This usually drives the design to have very thin classes that wrap
third-party code to implement an abstraction (e.g. interface) from my
application's domain.  Code that uses that interface can be tested
with mock objects.  Code that implements the interface by calling
third-party code is easy to test with integration tests or sometimes
has so little logic (e.g. none) that the end-to-end tests give
adequate coverage.

--Nat

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


 « Return to Thread: mocking concrete classes with final toString method