Lately, both at work and when working with the Page Type Builder project, I’ve been writing tests that tests methods that are very simple but quite long. While doing this I’ve been struggling with what tests I should have and how the tests should be written.
Let's say I have a large method that contains quite a lot of operations that are on the same level of abstraction. It could for instance be a method that updates a object based on some other object. Like this (imagine there are like thirty assignments instead of just two):
void UpdatePage(Page page, PageSpecification specification) { page.Name = specification.Name; page.Type = specification.PageType; }
One way of testing this method would be to create three different tests that tests each of the assignments, like:
void GivenSpecification_UpdatePage_updatesPageName() { PageSpecification specification = new Specification(); specification.Name = Guid.NewGuid().ToString(); Page page = new Page(); UpdatePage(page, specification); Assert.Equal(specification.Name, page.Name); }
Another alternative would be to create a singe test in which I create a expected object and compare the updated object with that. Like this:
void GivenSpecification_UpdatePage_updatesPageName() { PageSpecification specification = new Specification(); specification.Name = Guid.NewGuid().ToString(); specification.Type = new PageType(); Page page = new Page(); Page expectedPage = new Page(); expectedPage.Name = specification.Name; expectedPage.Type = specification.Type; UpdatePage(page, specification); AssertPageEquals(expectedPage, page); }
A third alternative would be to break up my method in separate, smaller, methods that I test individually. I would then test the main method by making the helper methods virtual, create a partial mock and test that the main method calls each of the helper methods.
I'm leaning towards the third alternative as it makes it very clear what functionality is broken when a test fails while keeping the tests simple. It will however require me to make the helper methods virtual for no other reason than to test them.
Any (preferably well motivated) suggestions are greatly appreciated!
PS. For updates about new posts, sites I find useful and the occasional rant you can follow me on Twitter. You are also most welcome to subscribe to the RSS-feed.
Similar articles
- Web testing with Selenium and xUnit.net
- Using MSpec – a few weeks in
- I have a crush on MSpec
- Setting Expectations With StructureMap’s MoqAutoMocker
- Rhino Mocks - Use Arg<T> ONLY within a mock method call while recording
- Learning Scala part eight – Scala’s type hierarchy and object equality
- Learning Scala part three – Executing Scala code
- Inversion of Control – It’s broader than just injecting components
Comments
comments powered by Disqus