|John Fallows||May 10, 2006 5:23 pm|
|Adam Winer||May 10, 2006 5:43 pm|
|Dennis Byrne||May 10, 2006 6:29 pm|
|Adam Winer||May 10, 2006 9:44 pm|
|Craig McClanahan||May 10, 2006 10:09 pm|
|John Fallows||May 12, 2006 9:08 pm|
|Craig McClanahan||May 12, 2006 9:15 pm|
|John Fallows||May 12, 2006 9:16 pm|
|Craig McClanahan||May 12, 2006 9:24 pm|
|John Fallows||May 12, 2006 10:12 pm|
|Craig McClanahan||May 12, 2006 10:32 pm|
|John Fallows||May 12, 2006 11:43 pm|
|Adam Winer||May 13, 2006 9:08 am|
|Martin Marinschek||May 13, 2006 2:46 pm|
|John Fallows||May 13, 2006 3:44 pm|
|Craig McClanahan||May 13, 2006 4:49 pm|
|John Fallows||May 14, 2006 11:14 am|
|Adam Winer||May 14, 2006 12:35 pm|
|John Fallows||May 14, 2006 9:47 pm|
|Matthias Wessendorf||Jun 19, 2006 3:31 pm|
|Subject:||Re: Thoughts about unit testing and mock objects|
|From:||Craig McClanahan (crai...@apache.org)|
|Date:||May 13, 2006 4:49:10 pm|
On 5/13/06, John Fallows <john...@gmail.com> wrote:
On 5/13/06, Adam Winer <awi...@gmail.com> wrote:
On 5/12/06, John Fallows <john...@gmail.com> wrote:
On 5/12/06, Craig McClanahan <crai...@apache.org> wrote:
On 5/12/06, John Fallows <john...@gmail.com> wrote:
On 5/10/06, Adam Winer <awi...@gmail.com> wrote:
I thought more about this over the last few hours. I think my basic gripe with easymock and mockobject approaches to JSF API objects is that most of the JSF tests I write rarely are concerned specifically with testing how my code is interacting with the JSF API; it's how my code is itself behaving. The former is where mock object suites pay dividends, but when your main concern is in your own code, mock suites seem to get in the way for more than they help. Basically, the Shale test framework seems like a better fit (yeah, handcoded, but that work's done and released...).
I don't understand your point. Shale test framework is founded on mock objects.
In addition, code we write in things like ADF Faces is going to assume certain behavior on the part of the JSF runtime -- I like to use a mock object framework that behaves enough like the "real thing" so that I can test the parts of my code that depend on that behavior too, not just static unit tests on individual methods.
Also, no one so far seems to have addressed the second question in
original post about how we should provide mock objects for our own
our unit tests.
It probably blurs the line between unit tests and system integration tests a bit, but I like to use the real objects, rather than mocks, whenever
feasibly do so. Besides having to do less work (not building mocks for classes that can be used both at test time and runtime), this also reduces the risk that I will mistakenly program my own class to the possibly botched behavior of a badly written mock object, giving me a false sense of security when the tests pass ...
Well I definitely agree about not wanting to hand-craft mock object implementations!
Dynamic mock creation also seems to address that by not requiring an implementation and keeping the recipe for the behavior isolated to the unit test itself. This provides self-documenting tests which are especially useful for anyone trying to learn the semantics of the code.
IMHO, unit testing is about verifying the semantics of each codepath
method, aiming for 100% coverage. This is most easily verified if each codepath is unit tested in isolation, preventing cascading failures and minimizing initialization overhead (only create the objects used by the method codepath).
The point about false positives is interesting. Let's assume that we don't have any reusable mock object implementations to possibly botch,
have a specification of expected behavior (to possibly botch!) inside each unit test method definition (using jMock).
This is, I guess, Objection #1 for me. Why put the burden of defining proper JSF behavior into every test, instead of into a reusable mock implementation? It's not just a question of effort - it's one of correctness, since if that behavior can be independently defined in each test, it can be defined differently in each test.
The intent is to specify a set of inputs to the method invocation to force it down a particular codepath, then verify the outputs either as a return value, or that methods interaction with passed parameters.
Maybe someone can provide an example of the behavior you are talking about that might become incorrect. Craig? Martin? I'd appreciate some insight here.
In an example that ought to be relevant for this codebase :-), consider what happens when you want to test the encodeBegin(), encodeChildren(), and encodeEnd() methods of a Renderer implementation. The methods return void, so the output isn't particularly interesting :-). What is interesting, however, is that the methods themselves are going to assume that FacesContext.getResponseWriter() returns somethng usable, even in a unit test scenario. Shale's MockFacesContext, for example, gives you back a mock writer that can write out to a buffer, which you can later examine to determine whether the component created correct markup or not (based on the properties/attributes you set on the component). And, this functionality is needed in all renderer tests, so it makes sense to encapsulate into a separate library that can be debugged once.
How do you approach this sort of scenario with dynamic mocks?