I find myself writing a lot of boilerplate mocking code for my unit tests. I think there must be a better way.
Background
I am working on a project that relies on complex configuration that is stored in a database. The API accepts an id, which is then used to load the configuration.
A very simple example:
public class FooProcessor : IProcessor
{
private readonly IRepository<Foo> repository;
public class FooProcessor(IRepository<Foo> repository)
{
this.repository = repository;
}
public string Process(string id, string data)
{
var configuration = this.repository.Get(id);
return this.ProcessHelper(configuration, data);
}
private string ProcessHelper(Foo configuration, string data)
{
// Do something based on the configuration and data...
return "TODO";
}
}
Current Approach: Mocking
So far, I have been unit testing this project by mocking out the DAL using Moq. However, that is cumbersome, because (1) lots of classes rely on the DAL and (2) the configuration can be quite complex. So I am writing a lot of boilerplate mocking code in my tests.
Another Idea: Load-First
Another option I considered is to refactor all my classes to accept the loaded configuration, rather than have a dependency on the database. I still want the public API to accept an ID, but the public entrypoint could load the configuration and pass it to all my other classes. Then in my unit tests, I could pass configuration objects to the methods I am testing, which is simpler than wiring up mock dependencies.
However, that idea breaks down in more complex scenarios. For example, I might need to load various pieces of configuration for some process. And I might not know what configuration I have to load up front. For example, I might load configuration A, then start processing, and realize I also need configuration B. So I don't think I can realistically only hit the database at the API entrypoint. But maybe I can still use some variation of this idea?
Another Idea: Integration Tests (instead of unit tests?)
Or perhaps unit tests are not a good fit given these requirements, and I should focus my efforts on integration tests with a real database?