Unit Testing Model-View-Presenter

S

Sean Chambers

Hello,

I am attempting to utilize the MVP pattern in a new app I am building.

I am using TDD, along with mock views attached to the View interface to
attempt to unit test the UI. The problem I am having is when using the
InitView() of the presenter, normally I would be retrieving data from
NHibernate when InitView is called.

Therein lies the problem, I can't seem to figure out how to properly
attach to the presenters from my unittest code, and then call InitView
without my production presenters actually connecting to the DB and
retirieving data.

For the time being i created dummy Initilizers, i.e., I have InitView()
that will be used in production asp.net frontend, and am using
InitViewTest() in my unit tests.

For this project I am not using any DAO classes, as it is a small app
that I don't see needing to scale much.

When you are using MVP along with Unit Tests is it in your best
interest to create a set of DAO generic classes for dataaccess via
NHibernate and then subclassing them with the actualy DAO objects like
I read in the NHibernate Best Practices tutorial?

That route just seems like overkill for me, as this app isnt that
large. Any help would be greatly appreciated!

thank you!

Sean
 
C

chanmm

Hello Sean,

Just make sure we are reading the same book at first. Are you read
"Enterprise Solution Patterns Using Microsoft .NET Version 2.0", 2003?

I cannot find NHibernate in the book anyway.

But you mentioned DAO. Just curious why not ADO?

Do you mind to share with me what is TDD?

chanmm
 
S

Steven Nagy

TDD = Test Driven Development (or Design).
Frameworks such as Nunit allow you to write test cases for your code.
Dependency Injection is a big consideration in TDD and thus the OP is
using Mock objects to mock the UI layer (View).

I think their question is not really syntactically specific, and thus
concepts like ADO are not relevant to the discussion.

Unfortunately I can not provide a reasonable answer to the question
myself, but would definately benefit from the answer so I am also
interested in what input people have about this.

SN
 
S

Sean Chambers

chanmm,

NHibernate : http://www.hibernate.org

This is an Object/Relational Mapper, it allows you to create
classname.hbm.xml files that map your properties in classes, to columns
in your database, then you simple make calls to the "NHibernate.Core"
supplying what objects you want, it generates sql to retrieve the data
you want, and returns the concrete object you are looking for.

This essentially does away with your data access layer (in a sense).
Hibernate is very mature (been around for java for awhile) and is open
source.

Microsoft is actually coming out with their own O/R mapper called
ADO.NET Entities. I haven't really done alot of research on it though
(shame on me). I've also been hearing about something called LINQ,
which I believe works into their piece of the puzzle some how.

when I am talking about DAO (Data Access Objects), I am referring to
objects that you create (that implement a base "GenericDAO" class),
that has special types of data retrievals you want to perform,

I.E.:

ICustomerDao customerDao = new CustomerDao(); // should really be using
a factory
IList<Customers> myCustomers =
customerDao.GetAllCustomersByRegion(string region);

Does that make a little more sense?

I have not even tried to start implementing Dao classes yet, but as I
stated before, a full blown, dependency injection/Dao classes are a
little overkill for this app I'm working on, if it is the only way,
then I will go ahead and try it out, just wondering if maybe someone
has a "A HA" that I'm not catching.

Some DI (Dependency Injection) frameworks I have been told about (but
not yet used) is Sprint.Net and CastleWindsor

TDD = Test Driven Development.
This allows you to setup "UnitTests" that test functionality of your
code in tiny incremental steps. The basic idea is, to test little tiny
bits of functionality so you ONLY implement what you NEED for your code
to perform its job. This makes for more readable, effecient, cleaner
code. I have begun using it on all my projects and I couldn't imagine
going back to not using it.

It is quite tricky to perform the actual unit testing in small modules,
and thats where the mock objects come in, NMock is what I use, it
allows you to setup "dummy" objects that are needed by a particular
unit test to perform functionality in other parts of your code. This
also promotes loose coupling.

Kinda went off on a rant there, =)

hope that clears some things up for you :)
 
C

chanmm

Hi Sean,

Sorry to say I can't help much I bet but somehow it sounds pretty much like
Visual Studio Team System to me. So, have a try :).

chanmm
 
S

Steven Nagy

I am using TDD, along with mock views attached to the View interface to
attempt to unit test the UI. The problem I am having is when using the
InitView() of the presenter, normally I would be retrieving data from
NHibernate when InitView is called.

I thought that in fact your Model would be dealing with nHibernate?
Which means you would need to Mock it as well. And in your case, a call
to the Mocked model object should return an object that has been
constructed from nHibernate.
Therein lies the problem, I can't seem to figure out how to properly
attach to the presenters from my unittest code, and then call InitView
without my production presenters actually connecting to the DB and
retirieving data.

Have you got a high level example?

Could be I am not exactly understanding the approach...

SN
 
S

Sean Chambers

Therein lies the problem, I can't seem to figure out how to properly
Have you got a high level example?

Could be I am not exactly understanding the approach...

SN

Let's say I have a Presenter that presents a username from the
database.

within the InitView method, I would be attaching the view to the model
like so:


public void InitView() {
ISession session = NHibernate.Session() // just for the example
this.view = session.Get(typeof(User), id); // User is the class
that attaches to the view
}

Now, this code is fine in the production enviorment, but in my unit
test, I don't want to be retrieving any data from the backend, I want
to mock the User object, but then how do I actually get the mock in
there, thats why I made the test method like so:

public void InitViewTest() {
User user = new User();
user.UserName = "sean";
this.view = user;
}

I guess what I'm looking for here, is what is the proper way to supply
my presenter with a mock object, so that I can effectively test MVP.
From all the books I've read, they always stress not to delve to far
into the chain while unit testing.

I think I'm just missing something simple here, I am imagining that the
piece I'm missing is Dependency Injection, but I'm not sure

Thanks

Sean
 
J

Jon Skeet [C# MVP]

Sean Chambers said:
Let's say I have a Presenter that presents a username from the
database.

within the InitView method, I would be attaching the view to the model
like so:


public void InitView() {
ISession session = NHibernate.Session() // just for the example
this.view = session.Get(typeof(User), id); // User is the class
that attaches to the view
}

Now, this code is fine in the production enviorment, but in my unit
test, I don't want to be retrieving any data from the backend, I want
to mock the User object, but then how do I actually get the mock in
there, thats why I made the test method like so:

public void InitViewTest() {
User user = new User();
user.UserName = "sean";
this.view = user;
}

The alternative is to find some way of taking out the
NHibernate.Session() call. If you have your own utility method to get
the session, you could swap *just that* out for testing, and mock the
session. From my own experience it's likely to be quite a lot of work,
but it should be okay. In Java Hibernate, you can actually leave the
session fetching code in so long as you mock out the SessionFactory
interface to return your mock session.
 
S

Sean Chambers

I guess thats where dependency injection comes in and Data Access
Objects, this way you can mock the DAO's, or so I believe.

Anyone have any more ideas?

thanks

Sean
 
J

Joanna Carter [TeamB]

"Sean Chambers" <[email protected]> a écrit dans le message de (e-mail address removed)...

| I guess what I'm looking for here, is what is the proper way to supply
| my presenter with a mock object, so that I can effectively test MVP.
| >From all the books I've read, they always stress not to delve to far
| into the chain while unit testing.

As with all well-designed OO software, separation of concerns is the key
here.

Your "data" should only be accessible from a separate "layer", so you need
to design an interface or abstract class that encapsulates the concept of
data access and then design "real" and "mock" layers that can be
instantiated, depending on whether you are testing or using the classes.

Joanna
 
S

Sean Chambers

I see, this is what I was leaning towards.

Even while using NHibernate, I guess you still need a DataLayer
assembly to return specific sets of data depending on the type of
request.

I guess this is where the DAO's come into play.

Thank you for everyones comments!

Sean
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top