Tests for Stub Classes

1 view
Skip to first unread message

Adam Dymitruk

unread,
Nov 13, 2007, 5:56:05 PM11/13/07
to alt...@googlegroups.com
Something interesting from the TDD forum...

---------- Forwarded message ----------
From: Adam Dymitruk <ad...@dymitruk.com >
Date: Nov 13, 2007 2:55 PM
Subject: Re: [TDD] Tests for Stub Classes
To: testdriven...@yahoogroups.com


I have seen some problems going event driven. If I have a rhino mocked view, I have to make sure to have all the events assigned to something before I could use any of them. This became a pain to maintain. You need an event raiser to be returned when you assign to an event handler and then use that to kick off the event. But that's only if you are mocking out the view and need to raise events.

Also, compiler does not check if your events are wired up. That's a run-time thing. This is not good. I like the compiler or resharper to scream at me if something is not up to snuff. So this is just another "oops, forgot to do that" after I waited 2 minutes for my tests to get to that one....

About the visibility of the presenter to the view:

The view doesn't know anything about the presenter. It knows only about an IViewObserver - it's just a coincidence that the presenter is implementing it and signs itself up as the observer for the view - but, shhhhh.. don't tell the view that ;0)

It's the same thing as an event. But events are not as navigable as an observer pattern. It's clumsier to walk your code when events are involved. You get loose coupling but also throw away code navigability and simplicity with events. With an observer, you don't have to know anything about event handlers, delegates or multicast delegates. You simply call something on an observer interface when something happens. You are still loosely coupled. The view knows of an interface but that's it. It has no clue as to what goes on after it calls the methods on it. With events you are doing the same thing but covering it with syntax.

Further with the syntax: It's a one step process to add something that the view is going to trigger. Just implement that new method on whatever is implementing IViewObserver. With events, you have the extra non-compile-time check to make sure you are subscribed to the event - this is probably the biggest beef I have with the event model. With the observer, you can't compile until you deal with the new method. That's a good thing in my books.

Remember, just because the presenter implements the IViewObserver, it does not mean that the presenter owns it. I think that one point alone clarifies the observer pattern for most people trying to understand it for the first time. For the passive-observed-view model, the view "owns" both the IView and the IViewObserver. The use of IView and the requirements that the IViewObserver dictates are the view's responsibility. This is why I use the word "view" in both interfaces. Notice "presenter" is not there. The two interfaces are just the glue between the two layers. They should not be considered part of one layer or the other - especially not the presenter layer.

In some cases you may want something else to implement the IViewObserver and have the presenter deal with that according to some other design. Here's some UMLish looking drawings (the view and presenter are supposed to be in boxes if you get the formatting wrong because of the font in your reader):
______                                         _________
|  view  |------> IViewObserver <|------| presenter |
|______|-----------|> IView <-------------|_________|   

or...
______                                      __        _________
|  view  |------> IViewObserver <|---|__|<--->| presenter |
|______|-----------|> IView <----------------------|_________|   


Your testing is now easier, IMO. All you have to do is call the presenter (or something else intermediate) through the IViewObserver interface to simulate the use of the view.

HTH,

Adam


On Nov 13, 2007 11:50 AM, Cory Foy <user...@cornetdesign.com> wrote:

Adam Dymitruk wrote:
> Have the presenter implement an IViewObserver. The view can be have a member
> that is of the type IViewObserver. Instead of raising events, the view just
> calls what the observer is interested in (like RefreshRequested())

Thanks Adam. I'd like to hear more about it, because I'm having a hard
time visualizing what makes that approach better than raising events. In
my current working, the view doesn't have to know anything about the
presenter, whereas it seems like the above would require me to have a
property I'd have to set in the view.

Have you seen problems by going event-driven?
Recent Activity
Visit Your Group
Y! Messenger

All together now

Host a free online

conference on IM.

Win free airfare

from Yahoo!

Fly home for the

Holidays on us.

Yahoo! Groups

Women of Curves

Discuss food, fitness

and weight loss.

.

__,_._,___


Reply all
Reply to author
Forward
0 new messages