1

I am dealing with an old .net code base which has a PrivilegeChecker static class with hundreds of static methods, each of which takes in some user id and some other params, and then fetches some info from db to determine whether the provided user has the privilege to do the thing. If not, then it throws an exception. This is being used in many places.

I am writing some new API functionality which has a class and a method which receives some requestData, validates a few things, looks up a few things as required, creates a new request object, and contacts an external API and then validates the response and passes back a response object. So far so good.

One of the things to validate is to do a privilege check using one of the static methods in the above mentioned static class. However, when writing unit tests for my functionality, I need to create a few mocks including the one for the external request. But I can't mock the static method that does the privilege check without creating some sort of a wrapper class to an interface around that static privilege checker. But like I mentioned this PrivilegeChecker class is hundreds of methods and I am not about to create a giant wrapper around that. So where to start? It seems creating a wrapper class around just a single method also seems excessive because it might eventually end up in hundreds of classes.

Are there any solutions around this?

1

1 Answer 1

4

Your idea of introducing an interface or wrapper class seems correct to me. By depending on an interface, you can avoid the dependency on the static class. The interface can be implemented by a class that just forwards the requests to the static privilege checker, and by other classes that serve testing purposes.

But like I mentioned this PrivilegeChecker class is hundreds of methods and I am not about to create a giant wrapper around that. So where to start?

By introducing an interface that only covers the methods that you need. There is no need for your code to depend on all the other methods, so the interface used by your code shouldn't declare them.

There are two ways to look at an interface in the OOP sense:

  • from the implementer perspective
  • from the user perspective

You have the implementer perspective that you're trying to abstract over a class with hundreds of methods. But from the perspective of a user of this interface, only a handful methods are needed – a much smaller and much more accurate description of the real interface. This idea, that interfaces are declared by users, enables dependency inversion. It occurs in various patterns like the “staircase pattern” or the “onion architecture”.

It seems creating a wrapper class around just a single method also seems excessive because it might eventually end up in hundreds of classes.

On one hand, this might not matter. Modern C# makes it very easy to create lots of small classes.

But more pragmatically, you might have a point. Serious dependency inversion leads to having lots of interfaces, lots of moving parts, that are unnecessary during normal execution. This makes the code more complicated and more fragile. So maybe the best approach is to create that interface with hundreds of methods after all?

There are however two strategies that might help limit this effort.

  • That the privilege checker has hundreds of methods does suggest that something has gone a bit wrong design-wise. It is very likely that these methods can be grouped in a reasonable manner, and that it could be decomposed into smaller interfaces that still are cohesive.

    For example, an application might have largely separate sets of privileges relating to admin tasks versus ordinary user actions. The code that deals with ordinary user actions should not have to depend on admin-only privileges. If the feature you're working on only relates to user-only actions, a lot of methods would already be out of scope for the interface you'd have to write.

    I suspect that classes/interfaces that have only a single method, or those that have hundreds of methods, are both suboptimal in your scenario. The best design is probably somewhere in between. A dozen interfaces of a dozen methods each is probably easier to manage. But this is NOT about the size or the number of interfaces, but about ensuring that each interface is cohesive.

  • Your interfaces don't have to be all-or-nothing. You can start with just the methods you need. Later, when other parts of the code want to use a similar testing/mocking strategy, the interface can be expanded to also cover those methods that this other code needs.

    The big advantage of working on an application (as opposed to a library with a public API) is that you can always refactor the internals. You don't have to start with a perfect design, and can instead take incremental steps. You can add more methods to an interface later because you also control all classes that implement the interface.

So unless the rest of the team has objections to that design, I would indeed start with creating an interface with the single method that you need right now.

4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.