CQRS architecture seems to be very popular. And I’m on that wave as well. In short CQRS is separating all read-actions from write-actions. And you have different classes for reading and writing. Queries for reading. Commands for writing.
For queries you would have IQuery and IQueryHandler interfaces:
public interface IQuery<out TResult>
public interface IQueryHandler<in TQuery, out TResult> where TQuery : IQuery<TResult>
TResult Handle(TQuery query);
For command you would have very similar set of interfaces:
public interface ICommand
public interface ICommandHandler<in TCommand>
void Handle(TCommand command);
There are doubts about if you should test registrations in you IoC container. I have been intimidated by this blog-post for a while and did not touch container for writing our tests. However, we did have a problem in the past, when DI container could not create one of our controllers. And we have lost days trying to chase the problem – there was no meaningful error message, because the real exception was swallowed somewhere in transit. It turned out that we have violated DI principal of a simple constructor: “Do nothing in constructor”. I have blogged about this before.
Today I would like to show how we test our IoC container to check if it can create all our controllers. Because controllers are immediate aggregate roots that are used by an end user. And controllers in MVC are the final consumer in the dependency chain. So if you likely to hit a problem in a chain of dependencies, it is likely that you will catch it by creating all the controllers.
Of course, if you use IoC container as a service locator or Mediator pattern you will have to test container separately for the types you get out from container there (mostly Command Handlers and Query Handlers).
While writing and testing ASP.Net MVC application, many times over I needed to simulate HTTP Request and presence of
HttpContext.Current. I need this mostly when I try to test code that interacts with MVC framework, like MVC Action Filters or custom Model Binders or testing routes.
ASP.Net MVC 4 is quite good in this matter – most of the framework can be replaced by a mocked object and there is a minimum number of static calls or sealed objects. So you can do the HTTP Simulation, but usually it involves a lot of boiler-plate code and many mock-objects to be set-up.
Update: There is an updated implementation of this code: see this blog post
One of my applications has a feature where it is given a URL with Shared Access Signature to Azure Blob Storage and then via REST API it uploads files to the storage. You can do that by provided Azure Storage libraries. Originally I had that functionality implemented with these libraries. But now I’m slimming down the application (this is a small command line app) and getting rid of unnecessary dependencies. And for the sake of one upload method I don’t want to tie myself to masses of extra DLLs. So I’m replacing the libraries with REST API call.
I have spent some time trying to test this functionality. You may say that this is a not a unit test. Yes, it is not a unit test. Other questions? Also you may say that you shouldn’t test these kind of things and wrap a class around these and ignore. That is what I have done in the past, but that particular piece of code caused an endless pain because I’ve done it all wrong and it was not covered by tests.
For my unit tests I’m using an awesome tool Autofixture as data generator and as an Automocking container. But by default for creation of objects it uses the constructor with least number of arguments. Mark Seemann talks about this in his blog. Also he provides code on how to make Autofixture work the opposite way. But the code example in that blog post is outdated and no longer valid in the latest version of the framework.
So every time I need this (and this is not often) I have too search for the solution over-again. And just to save myself this research next time, I’ll put the solution here:
var fixture = new Fixture();
fixture.Customizations.Add(new MethodInvoker(new GreedyConstructorQuery()));
It is vital for your application security not to show any internals when error happen. And you should be able to replace all internal error messages to nice user-friendly pages. It is a just nice for users – they are not getting splashes of oil, when engine is exploded, also another measure to improve site security.
There are lot of articles about error handling in ASP.Net MVC, but most of them do not cover the whole range. There is a very good resource on this, and I do recommend reading and understanding that first.
With error handling there are a lot of edge cases, and for every single one of them you need to provide a solution, otherwise your error messages will talk too loud about your implementation and that can lead to security vulnerability.
In my last post I talked about ELMAH and how you can override connection string. But Atif Aziz (ELMAH author) pointed out that there is a better way to do that:
Fair enough, I thought. I did see that solution when originally needed to fix this problem. But I did not manage to quickly reproduce the code, so I went with a hacky way. This time I’ve spent a couple hours for that and did get what I wanted without dirty hacks.
ELMAH is a nifty tool that allows to you record exceptions that arise in your web-application. It is very handy and everyone should use it in addition to application logging. But if you are using Dependency Injection and have your connection strings provided by some service, then you might have trouble. For example, in our app, we use Azure Configuration settings and we have a service
IConfiguration that has a lot of get-methods for different config settings in our app, including database connection string.
In the previous blog post I wrote how it is important to have a simple constructor that only accepts dependencies. And violation of this rule cost me at least 12 hours of debugging and blocking issue for some developers in the team. Now I have a unit test to prevent this kind of problem in the future.
One of the suggestions in the comments was to use strict mocks and inject them into a controller. And don’t set up any kind of expectations on mocks. This way if dependencies are doing anything in the controller, they will fail the test.
Whole day of yesterday I’ve spent debugging some “random” error that came up third time during this week. The issue did go away after some tribal dances around the code, but two other instances did not get resolved easier. The biggest problem was that only one of the developers on the team did get the issue, and everybody else were not affected. And the same happened in the new deployment. And the issue was quite major – the whole site did not load. Nothing beyond the login screen. And it was impossible to hook in the debugger, it was bypassing all the breakpoints.
I would’ve gone through the issue and try debugging it, by my machine was not affected by the problem. I could not reproduce the issue locally. But on my home machine the issue came up. Strange I through, but was glad it came up – means I can dig my teeth deep in the problem and debug it.