Arguments in Stubs and mocks

Below is an informal email to work mates. Please note I am not the boss, I am a lowly contractor at the bottom of the heap, The devs I work with have a refreshingly open communication channel and I tend to have a bit more experience in Testing/TDD

*****
Hey Guys
I think I have unfortunately let some bad habits of mine slip over to you guys.

Some basic rules of thumb:

-Stubs should be used by default to isolate dependencies, use mocks when you are mandating that the SUT is incorrect if it does not interact with the given dependency.
-I will often declare in a test method set up the class level dependency to be a mock (with associated verify in the tear down), however that does not need to have expectations. You can always use the stub method on a mock, meaning failure to call that method will not fail the test.
-Use correct arguments and return values. Returning null and using the .IgnoreArguments() method should be last resorts and are generally a sign (if it is my code) of laziness or haste. Don’t do it unless it actually makes sense for the test.
-When returning null from a stub or mock the SUT should be handling it properly. I.e. what if that dependency actually did pass back a null? Is that even valid? Should we be handling it?

The major problem I find is the ignore argument method, I abuse it far too much when mocking, and I see it creeping it others work (not just ours but external code too!). Note: Ignore Arguments on stubs is not so bad, as a stub should not fail a test

RhinoMocks has the ability to specify argument placeholders that do not have to be the exact reference type that is being used e.g.:

timesheetService.
Mock(s => s.SaveNewTimesheet(

Arg.Is.Equal(creationDto)
))
.Return(new TimesheetDetailsDto());


Which is much better than:

timesheetService.
Mock(s => s.SaveNewTimesheet(null))

.IgnoreArguments()
.Return(null);

Be sure to override the equals method to accurately reflect the equality tho, otherwise the default of reference equality will still cause the test to fail!

Manning Book Reviews

Thought i’d let you guys know of some books i have been reading that are pretty good, They are all from Manning which I am really starting to like that publisher more and more.

JQuery In Action: Within about 90 minutes of reading this book you will understand the fundamentals of jQuery and be ready to do basic, but powerful, jQuery code. If you are using javascript natively seriously consider switching to jQuery and get this book. jQuery also has a test framework (QUnit) and a great suite of UI plugins (jQuery UI)

Art Of Unit Testing: Easily the best unit testing book I have read (and I have read a few). Great for newbies and those still getting to grips with how to test anything more than the most trivial of examples. It is the book i would recommend to people looking to learn to do TDD well. Note the examples are in C# but they really dont require indepth knowledge of .Net, in the same way all the other books are in java and I havent written a line of a coffee flavoured code in a decade. In saying that the tools are all .Net based but i am sure there are Python, Ruby and Java equivilents avaliable for most.

NHibernate in Action: Pretty much the same as the Hibernate book but shows all the .Net stuff you can do. its also a bit more up to date that the original Hibernate book (which has since had a second release). .Net devs nusing NH need* this book.

IronPython in Action: not a bad book… it does exactly what it intends, it teaches .Net devs about python on the CLR. The question is: Do you care? For me it was something of interest, i doubt I’ll ever use it in production. As a side note for the .Net kids i think the path of C# => Boo => Python =>Ruby is the one to take for the typical C# developer**. It keeps the “barrier to entry” low for the next step so you are picking up one new thing at a time (ie new syntax, dynamic language contrainst, DSLs and other scripty weirdness) and by the end of the process you have 4 languages under your belt in about the same time it would take to do the C# => Ruby jump.

that’s all

Rhys

*OK no one needs anything, especially as the NH doc a pretty good, but you will be severely hindered without it.
** VB.Net devs; you know you will never learn another language, you have had years to do so!

Simple reusable DTO factory methods

I have just found a little bug in my app that to me was an issue with code duplication. It was a DTO not getting properly hydrated when is was getting translated from a domain object in the service layer. My DTOs are just objects with auto properties, no business logic methods; just data carriers. I sometimes have the need for a basic DTO with just simple info (ie for Lists) and a more detailed DTO with the objects child collections (as DTOs collections) for more detailed views. The problem I had was when I added a field on to the domain object then had to modify my factory (and test) to ensure the new field was mapped. What I forgot to do was to also do it for my detailed DTO. I wtote the test and realised that I was doing the exact same work in 2 places, which was one of the reason behind the bug. As i prefer not to use anything other than a default constructor for DTOs i was in a bit of a quandry. Other than using JBogard’s AutoMapper i was not sure how to tackle this.
My goodness, i may actually have to engage my brain!
Well the result was incredibly simple.
The detailed DTO (xyzDetailedDto) inherited from the normal DTO (xyzDto) so i just created a private generic factory method in the publicly exposed Extension method class

private static T Create(xyzDomianObject domainObj) where T : xyzDto, new()
{
return new T
{
Id = domainObj.Id,
Name = domainObj.Name,
Details = domainObj.Details,
OtherThing = domainObj.OtherThing
};
}

As xyzDetailedDto inherited from xyzDto I could reuse the creation method and get back the correct type.
This all seems very simple and silly now, but this has drastically cleaned up my translation layer 🙂

Measuring Productivity

LOC is possibly the most stupid way to measure productivity. It really doesnt show anything and possibly encourages bloated code for the not so noble coder keen to grease up to the project manager.
Possibly a better option is measuring based on passing Unit Tests.
Why?

  • A unit test usual defines one part of functionality.
  • It encourages the developer to write untis tests and encourages more robust coding.

This is kind of a brain dump, but i think it may have merit…possibly.

"Just one test!"

I have read in a couple of places now (amongst other generalities) that a unit test per method is the standard “rule of thumb”. I have been surprised at this. I understand that at least one test per real method (not one line getter/setters) is a minimum but to generalise it to only one is a bit odd.
This was kinda sparked off by this post http://blog.sidu.in/2007/06/pre-run-tasks-unit-testing-anti-pattern.html. I am not coming down on the poster at all and I may have over reacted to an aspect of the post that was certainly not the main point of the thread.
But just one test per method? It got me thinking.
I generally have a test to cover each of the paths in the method (to an extent).
I never really thought about it but I guess complete coverage* would come from tests that match each of the paths and therefore the cyclomatic complexity of that method. If you have an increasing number of tests for a method you may want to reconsider the functionality of the method. Can it be refactored?
This I believe is another benefit of TDD. It forces you to think about function design first not just start the torrent of code and hope that what comes out works. This is also a reason to write the tests first. I find it amusing that some still write the test after they write the code. I mean really, why not define what you want then build it.

* no im not a coverage nazi :p

False Economies

As I get older and more experienced in the IT game some basic truths continue to rear theirs head… One I am currently running into is the idea of not doing some standard practice thing because it will “take to long” or “cost too much money” to do.
I have no problem with not doing some because it is too expensive, however when you are building a business critical application for a publicly traded, Tier 1 company, you had better make sure that those things that you are not going to implement don’t bite you in the ass later.
Documentation and Unit testing should not be negotiable. Especially around business object and other lower level layers. If these layers are not working correctly, how can the layer dependent on these be reliable?
One thing I see more often than I like is not putting enough emphasis on DB design. If you are using a very basic OO model and the DB is literally just a persistence layer then I am all for ORMs. If you have complex set based structures, hire a good DB geek that can architect a proper data persistence approach in terms of DB design and helping with Data Access. Often a developer is not the right person to be doing this.
(I think I have already emphasized this enough on this blog)
Another issue is allowing for future changes. Udi Dahan proposed a design principle which I agree with and employee:
For any classes A and B in a system where both A and B have behavior, A should interact with B through an interface.
The interface which separates two concrete classes should be packaged separately from either of those classes
By employing the strategy above, you allow for the ability to have tests to isolate each “layer”. You also then allow for changing of dependency. As long as the new class implements the original interface, how the business logic occurs is irrelevant. This came up specifically this week with regards to the data access layer. Using this strategy we could investigate different options in terms of the DA, such as using the current implementation, a modified version of the current, an ORM or a Generated layer based on the DB schema. If this had been done earlier it would have take lesser than a minute for each class. Not really a huge time loss there.

I dont take all of this as bad things, it is learning from mistakes, whether they be yours or others. The point is we need to learn from them so we can find ways to avoid or fix future encounters.