views:

115

answers:

3

So a coworker and I are in a fairly heated debate. We are beginning a new project and we are attempting to use BDD. We are both first-timers and don't fully understand what practices should be used. We've written some specs and we are now implementing the code. Things are getting pretty tricky since there is a lot of database interaction. We are stuck on how we should mock our data. The method we were going about would require us to mock our methods instead of our data. It's easiest if I show you in code...

public static void AssignLeadToDistributor(int leadId, int distributorId)
{
    Lead lead = GetById(leadId);
    lead.DistributorId = distributorId;
    Save(lead);
}

Basically, we would have to override GetById() and Save() to return mock data for us to test this. It seems to make more sense to do it like this:

public static void AssignLeadToDistributor(Lead lead, Distributor distributor)
{
   lead.DistributorId = distirbutor.Id;
}

Then we could just mock our objects.

Clearly the second method makes it easier to test. However, the argument is that we don't want to have to fetch a new lead and distributor object on our front end code, because it would be easier to just pass the ids of our objects. Cutting down on the actual code in our front end.

Hopefully I explained that well enough.

What do you guys think? Which way makes more sense?

+7  A: 

I think the biggest problem you're having is because you're using public static functions (which is usually a bad thing in OO languages).

I'd suggest moving this function to the Lead object, something like

public AssignDistributor(int distributorId) {
   this.DistributorId = distributorId;
   this.Save();
}

Easier to test, and more OO-like code =)

Samuel Carrijo
+2  A: 

I like the second method better, for the reason you stated: you can mock the parameters easily for testing. Are you using a dependency injection framework? If not then you I'd recommend you program your methods using the Dependency Injection principle anyway for more modular, and easy to test code.

And I agree with Samuel that you need to avoid using static methods whenever possible, or you'll find it very difficult to test-drive them.

Alex Baranosky
+1  A: 

What we do in our BDD specs (executable stories), is to not mock the DB at all, but instead use an in-memory DB (SQLite in our case).

Also, we initialize the container before any scenario runs. This is because we'd like our BDD specs to mimic the real world as far as possible, while still having the speed of ordinary unit tests.

By defining our BDD specs this way, we've found the need for unit tests and integration tests decrease, and gained both increased productivity and understandability (although very subjective since you can't really measure those metrics).

Martin R-L
This is kind of the route we ended up going. It's working great.
Kevin Wiskia
Super :-) We appreciate this method more and more as well.
Martin R-L