I’ve a web page that has many constituent parts.
On some user action, a POST operation is made, which then returns JSON to update the page. The problem is that this JSON payload contains a lot of information built from many different operations and classes. The JSON data is used then to update a number of partial views via the Ajax callback.
My question is, what is the best way of unit testing this? Should this one action method even be responsible for collating all this information and returning in one chunk, or should it be done via a number of Html calls to different actions from the web page? That would I think be easier to unit test.
Currently I may write 8 tests against a single action which I generally have to mock a number of operations which are not needed for some tests.
1
In my opinion Actions should be relatively small and delegate work to other objects. Actions should (again, in my opinion) simply be responsible for the following:
- Receiving the request
- Delegate work to other objects
- Return the result in the correct format
If you do this then unit testing becomes much easier through the use of mock objects and Dependency Injenction. Each object can then be unit tested independently.
I can write up a small code sample later if needed.
If a method is too large to effectively unit test- meaning it is most likely doing too many things for one method- then there are two approaches you can take:
- Split the method into several methods to be called sequentially
- Abstract parts of its functionality behind other methods
In your question you seem to focus on 1, but most of the time, 2 will be the better option, and in this case you’re already aware of the problems that 1 causes- you’d have to make extra calls from the browser to the server, for example.
There’s two ways you can extract methods, either to private methods on the same class, or public methods on another class. Private methods don’t help with unit testing, so generally as long as you’re able to make cohesive classes for the extracted methods which make sense and follows SOLID principles, then that’s the best bet. This is very commonly done in MVC, which is why people talk about having thin controllers- the meaty work is done by service classes which the controllers call out to.
From there, you can use the usual unit testing technique of mocking to test your now much smaller methods in isolation from their dependencies.