Unit Test and Test Driven Development in ASP.NET MVC application
This article aims to summarize the concept of testing which can help you while writing tests using any framework out there. I will be writing more on this topic and will also attach any relevant demo applications on github.
Types of Testing
There are many types of testing that you may want to apply to your application, namely:
- Unit Test & Test Driven Development (TDD)
- User Interface Testing
- Integration Testing
- Acceptance Testing
- Performance Testing
- Accessibility Testing
- Security Testing
Testing with ASP.NET Web Forms
If you are coming from ASP.NET Web Forms background and if you have done any testing in it, you may have find that it is not that easy to test your application because web forms aggregates and integrates the logic and the display i.e. view of your application. And this is what it makes testing very difficult.
Testing with ASP.NET MVC
The concept of Model View Controller (MVC) is designed by keeping testing in mind. The design of an application based on MVC concept makes an distinction to have a separate Model (data), the display of the application i.e. View and the Controller that has the logic to bind the Model to the View.
Below are some resources that you will need to test your MVC application:
- Visual Studio 2010/2012/Express 2013 (RC)
- One of any testing software framework – nUnit or xUnit or MSTest.
- Mocking Framwork – There are many free frameworks available out there but I’m going to use the free version of JustMock.
- You can also download nUnit Runner – that doesn’t depend on Visual Studio and runs independently.
There are couple of Caveat that we need to discuss before discussing the key concepts of testing an application:
- There is no one right way to test.
- Testing is something relatively new in the software development industry and people have different views to how to organize your tests, code, etc. This subject is open to discussion.
- There is no one right way to refactor. You & your team should adapt the same pattern of the way to refactor so as to run on the same track and make a good design of your application.
- Best practices – even these are subjective. Stick to something what the community follows and then extend it as per your needs.
MVC and TDD
- Test a single unit – a Class or (better) a method.
- Test in isolation of one another and to rest of the application. Test very small unit of functionality of your application.
- Uses Unit Testing to drive the design of your application.
- Is all about Test-First approach.
- There is a term referred as Red Green Refactor, which means
- Red Phase – create a failed test.
- Green Phase – write just enough code to pass the above failed test.
- Refactor Phase – clean up you code and then retest it to make sure your refactoring has not affected your test and it runs well.
- Repeat – repeat the above process again from Red – Green – Refactor phase.
Robert C. Martin’s Laws – known as Uncle Bob in the community
Uncle Bob has mentioned three laws to keep in mind while writing a successful TDD:
- Write no production code until you have written a failing test.
- Write no more in your unit test then enough to make it fail.
- Write no more production code then enough to make it pass.
Key points to remember whilst you write your First Test
- Test one feature only.
- Write the above test, run it and see it fail. It’s very important to see it fail – because only by seeing it fail you can have the confidence when you see it pass that you have corrected the issue.
- Fix only enough so that your test can pass. It’s very important – don’t get ahead of yourself to make a pass for your test anyway.
- Remember YAGNI – You Ain’t Gonna Need It . Sometimes you often end up working and spending time on something that you won’t need later, so, avoid that.
- If no. 3 above is not followed then you are writing something which is not tested and may be will not be tested in the future as well as many of the code that you have written just makes pass for the test very easily.
- Run your test and see it succeed.
- Refactor and retest – to see your refactor has not broken the test.
- Repeat the whole process from no. 1 above.
- It’s a way to see if you have in fact succeed i.e. what you expect to be true.
- Normally using any testing framework, you will find the keyword – “Assert” to make an assert of what you expect to be true.
- Rule to remember: You should have only one “logical” assert per test. It’s fine to have one or more assert statement but logically you should test just one thing and to ensure what is reason that your test should fail.
- There are many aspects that you can check while asserting namely,
- Equality – AreEqual, AreNotEqual, etc.
- Identity – AreSame, AreNotSame, Contains, etc.
- Condition – IsTrue, IsFalse, IsNull, IsNotNull, IsNan, IsEmpty, IsNotEmpty, etc.
- Type Checking – IsInstanceOf<t>, IsNotInstanceOf<t>, IsAssignableFrom<t>, etc.
- Exception Throw or not thrown.
- String – Contains, StartsWith, EndsWith, AreEqualIgnoringCase, IsMatch (regex), etc.
- Collection – AllItemsAre… InstanceOfType, NotNull, Unique, Equal, Equivalent, etc.
- File – AreEqual, AreNotEqual, etc.
- Driectory – AreEqual, AreNotEqual, etc.
- Asserts to force a result – Assert.Pass, Assert.Fail, Assert.Ignore, etc.