Suppose I have an interface declaring the following method signature:
SearchResults SearchProducts(string type, string filter, string anotherFilter);
Inside a concrete implementation of this, I instantiate a helper class (call it
QueryBuilder), built to ease the construction of strongly-typed search queries for the specific search library I'm using. I want to unit test
SearchProducts (ideally by mocking the query builder), which means I need to decouple the method from
How do I do this appropriately when the two things are logically coupled? That is to say:
- It's not appropriate to pass an
IQueryBuilderinto the method as the implementation of
IQueryBuilderis tightly coupled to the implementer of
ISearchProducts, i.e. the types of the return values of
QueryBuilder's methods are specific to the library being used in the concrete
- It's not appropriate to pass an instance of
SearchServiceconstructor (via DI or directly) as the logical scope of the query builder instance is local to the
SearchProductsmethod call - it is instantiated in the method, its state is manipulated by adding sub-queries and a complete "query" is extracted for this
So, given the above, what's the appropriate way of handling this? It sounds like a case for a factory; however the implementation of this factory would be trivial and it seems a little contrived to define a factory interface and add a constructor parameter just for the sake of testability.
Is this indicative of a fundamental flaw in the design of my search interface? How do I decouple these things appropriately such that I can test both the search service and the query builder implementations in isolation?