I am trying to retrospectively unit test an application that is fairly complex but utilises MVC. I know retrospectively applying unit tests isn't ideal but I still believe it's possible by refactoring existing code. A majority of the time it is not possible to unit test one unit, without relying on other units i.e. a view relies on a model.
What is the best way to unit test in this case? Is it better to utilise the real model or create a mock model?
The problem with utilising a real model in my situation is that the model relies on other response classes that get data from XML so there's a chain of reliance. This model has a lot of data so it would be much easier to use this but maybe I'm missing the point.
I have provided a UML of the application for brevity.
**Edit ****
Ok so if I am correct, is it best practice to create mock data inside a mock class? for example I have the mock class "MockPlaylistPanelModel" that creates data required for the View class "PlaylistPanel" to run without errors:
class MockPlaylistPanelModel extends Mock implements IPlaylistPanelModel
{
/**
* Return all playlist items
* @public
*/
public function get mainPlaylistItems():Vector.<PlaylistData>
{
var playData:Vector.<PlaylistData> = new Vector.<PlaylistData>;
var playlistResp:PlaylistData = new PlaylistData(0, "", "", 0, 0, 0, 0);
playData.push(playlistResp);
return playData;
}
}
Tests should never depend on each other. If your tests have to be run in a specific order, then you need to change your tests. Instead, you should make proper use of the Setup and TearDown features of your unit-testing framework to ensure each test is ready to run individually.
Among all of the other things that unit tests are, they are also tests of modularity. If it's difficult to write a test for a code change, your code could be more modular, and the modules should be relatively small.
Good unit tests should be reproducible and independent from external factors such as the environment or running order. Fast. Developers write unit tests so they can repeatedly run them and check that no bugs have been introduced.
Designing the test is the first thing to do before conducting a module test. For preparing the test case, you must consider two essential factors- module specification and source code under test. It is imperative to analyze the code logic for the module under test. You can do that by using multiple white box methods.
To retrospectively fit unit testing into an existing application, you often need to change the application code to support unit testing (as you rightly mention you may need to perform some refactoring). However of course the risk here is changes to the application introduce bugs, which cannot be protected against without having some tests in place.
Therefore, a sensible approach is to get some system level tests in place covering some of your key use cases. This acts as a kind of 'test scaffolding' around your application, meaning that you can more safely begin to introduce lower level tests with a decreased risk of introducing bugs as you modify the application to make it more testable. Once this is in place, you can then introduce a policy that developers must write tests around any code they change before they change it - this allows you to organically grow a set of automated tests around the application.
I would highly recommend getting hold of Working Effectively with Legacy Code - this excellent book covers all sorts of useful techniques for introducing testing into an existing application which has little automated testing.
Regarding your question on whether you should create mock data inside a mock class for testing, this is one approach you can take when injecting test versions of objects, but probably not the best. By using a mocking framework like Mockito you can easily create mock objects with clearly defined behaviour on the fly. In your case, you can use Mockito to create a mock model implementation, and then inject your mock model into whatever object depends on it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With