Should static classes be avoided because it makes Dependency Injection Difficult? - c#

Somebody tasked with creating a "Core" set of libraries created a set of static classes providing all sorts of utilities from logging, auditing and common database access methods.
I personally think this stinks because we now have a Core set of libraries that are hard to test because I can't mock / stub these classes or do any injection into their constructors.
I suppose I can use TypeMock to stub these out but I'd rather do it for free.
What do you think?
Edit
If you don't think they're hard to test could you give an example of how you would test them. These static classes instantiate other types to do their functions.

Static classes (methods) do not necessarily have to be avoided as long as they have no hidden dependencies. Of course you can pass dependencies into a static method - it just should not be stored internally and modify the behaviour of later calls.
There should be no problem to test them in this case, too.
But I have a bad feeling about the cases you mentioned, too. I know some of these static "wrapper" utility classes - and in most cases they really stink :)
EDIT:
Maybe I should clarify. I would use static classes/methods only for very small distinguished tasks. When static classes start to initialize dependencies they certainly should be avoided. If you can't test these static classes they already have a too big job to do.
In the first answer of this question are the arguments against static classes as you mentioned.

How hard would it be to modify those static classes to utilize Dependency Injection? If you make the DI optional (if possible), you can essentially make a situation where you can use the static classes for mocking, just by properly doing the DI, while not changing any of the "normal" behavior.

Following is from Journal of Object Technology: Decoupling responsibilities from static methods for fine-grained configurability
Static methods pose obstacles to the development of tests by hardwiring instance creation. A study of 120 static methods in open-source Smalltalk code shows that out of the 120 static methods, only 6 could not equally well be implemented as instance methods, but were not, thus burdening their caller with the implicit dependency on these static methods

Related

C# static constructor in instance class -- Pros & Contras

I use static constructor in instance class to make this class initialization with some Resource constants. My more experience colleague remark, that it is bad C# style as any static in code. More reliable with his opinion is external public readonly class for this.
However, VisualStudio C# provide run of internal static constructor at first address to common resource, vs external class, which i should call from higher program level. Isn't it a source for additional errors? Am i correct with this logic?
The question you ask is about coding style. Some prefer using static, some prefer to avoid it.
Static can be very helpfull and there are a few features which rely on static. For instance Main, Class Extension, Singleton pattern.
I was greatly using static for my own code because it makes a lot of things easy (you don't have to worry about building the shared stuff). However, when I started doing unit testing I felt more and more unconfortable with it. Static data by definition will be created once and shared which means that for unit tests this data will be shared by the tests. It makes tests independancy much more difficult, forcing you to reset manually everything in your Setup/Teardown methods.
In a few words, for the purpose of unit testing and modularity, I would discourage you from using static constructor for data which isn't immutable (or at least that you use as immutable -> read only access). Immutable data is not an issue as it won't be altered while the program (or the tests) run and you can always be confident about it's value.
Again this is some kind of coding style and some people will disagree and that's fine (as long as they know why they prefer another style)

Testing static classes and methods in C# .NET

I'm relatively new to unit testing, and very new to C#, but I've been trying to test code that uses static classes with static methods, and it seems like I have to write huge amounts of boilerplate code in order to test, and that code would then also probably need to be tested.
For example: I'm using the System.Web.Security.Membership class, with a method ValidateUser on it. It seems like I need to create an interface IMembership containing the method ValidateUser, then create a class MembershipWrapper that implements IMembership, implementing the method ValidateUser and passing the arguments on to the actual Membership class. Then I need to have properties on my class that uses the Membership to reference the wrapper so that I can inject the dependency for a mock object during testing.
So to test 1 line of code that uses Membership, I've had to create an interface, and a class, and add a property and constructor code to my class. This seems wrong, so I must be getting something wrong. How should I be going about this testing? I've had a brief look at some frameworks/libraries that do dependency injection, but they still appear to require lots of boilerplate, or a very deep understanding of what's going on under the hood.
I don't see anything wrong in making your system loosely coupled. I believe you don't complain on creating constructor parameters and passing abstract dependencies to your classes. But instantiating dependencies in place looks so much easier, does it?
Also, as I pointed in comments, you can reuse wrappers later. So, that is not such useless work, as it seems from first glance.
You are on the right way, and think you are not testing single line of code, in this case you are writing important test to ensure that your code interacts with membership provider in the right way, this is not simple unit test rather "mock-based" integration test. I think it worth creating all these mocks and have covered by tests this part of application.
And yes, it seems overkill but no other way - either you use some helpers/libraries either wrap third-party static dependencies yourself.
I you're not happy taking the approach of constructor injection, you could look at using Ambient Context
You basically set up a default which will call System.Web.Security.Membership.ValidateUser
You then call the exposed method on the context in your code and you can now mock it for your tests
This allows you to write less setup code, but it also hides the fact that you have a dependency, which might be a problem in the future (depending on how you're reusing code)
If you're using VS2012, you can always use Shims in Microsoft Fakes for static calls (or .Net library calls too).
http://msdn.microsoft.com/en-us/library/hh549175(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/hh549176.aspx

Unit tests in same class (with conditional compilation)?

I'm aware of (and agree with) the usual arguments for placing unit tests in a separate assembly. However, of late I've been experiencing some situations where I really want to be testing private methods. The behind-the-scenes logic in question is complex enough that testing the public and internal interfaces doesn't quite get the job done. The testing against the class's public interface feels overwrought, and I see several spots where a few tests against privates would get the job done more simply and effectively.
In the past I've tackled these kinds of situations by making the stuff I need to test protected, and creating a subclass that I can use to get at it in the test framework. But that doesn't work so well on classes that should be sealed. Not to mention bloating the test framework with all that scaffolding.
So I'm thinking of doing this instead: Place some tests in the class, where they can get at the private members. But keep them out of the production code using '#if DEBUG`.
Does this seem like a good idea?
Before anybody asks...
The solution to OP's problem is to properly incorporate IoC with DI and eliminate the need of testing private method altogether (as Joel Martinez noted). As it's been mentioned multiple times, unit testing private members is not the way to go.
However, sometimes you just can't change the code (legacy systems, risk of breaking changes - you name it) nor you can use tools that allow private members testing (like Typemock, which is paid product). For such cases, you can either not test at all, or cut corners. Which I believe is situation OP's facing.
Leaving private methods testing discussion aside...
Remember you can use reflection to access and invoke private members.
In my opinion, placing conditional debugs in the class itself is rather bad idea - it adds noise (as in, something unrelated) to the class code. Sure, it will be gone in release, but you (and possibly other programmers) will have to deal with it on the daily basics.
I realize your idea might sound good on paper - simple test wrapped with conditional debug. But in reality, tests quickly turn out to use extra variables (those will also have to be placed in the class code), some utility (extra references, custom types), testing frameworks (even more references) and what not. This all will have to be somehow connected to the class code. Put that all together, and you quickly end up with an unmaintanable monster.
Are you sure you want to deal with that? Especially considering that throwing together simple reflection-based utility is probably not that hard.
Everything you're referring to can be solved with just two concepts: Single Responsibility Principle, and Dependency Injection. It definitely sounds like you need to simplify your classes. Mind you, that doesn't mean the class must offer less value, it just means that the internals need to be simpler and some functionality may have to be delegated to others.
If you need to test this method independently of the public API of the class, then it sounds like a candidate for being removed from the class itself.
You could say the class is dependent on the private method (as is arguably evident by the need to test it separately from the class public API).
If this dependency cannot be satisfied through testing the public API of the type alone then have the class instead delegate this dependency to another type. You can either instantiate this type internally or have this type injected / resolved.
This new type can then have its own unit tests, as it's public API will be expressing what was previously a private method.

Unit testing C# refactoring static methods

I have some classes(call it Class A) which I would like to unit test but it uses some classes(call it Class B) with some static methods.
To remove reference to these classes with static methods I have to refactor them to be instance methods and inject into Class A.
Issue is Class A has lots of services(Not only class B) its seems to depend on?
What is the best option in this scenario? Have a constructor that has a lot of parameters that can take in these services?
Or is there something wrong with my design the fact that class A has so many dependencies?
Thanks
Issue is Class A has lots of services(Not only class B) its seems to depend on?
Several dependencies are usually indicating a code smell. Your class is most likely breaking Single Responsibility Principle.
Try to break down the class into smaller classes.
Unit tests are a good quality indicator. Classes that are hard to test are often violating one or more of the SOLID principles.
What is the best option in this scenario? Have a constructor that has
a lot of parameters that can take in these services?
Constructor injection is always the preferred way since it's easy to tell what dependencies a class has.
I would recommend constructor injection, especially if you have a lot of dependencies to inject, only if you're using a Dependency Injection framework like Unity or Ninject. Refactoring an existing code-base to add constructor injection everywhere is usually messy, and probably requires storing all the services in local variables in many base classes just so you can pass them on to classes further down the chain.
What I would do in this case is use some implementation of the ServiceLocator pattern, with a single static ServiceLocator/Container class that you can use to access your non-static services:
IService _service = ServiceLocator.GetService<IService>();
This will require the minimum amount of refactoring in existing code (just replace MyService.DoSomething() with _service.DoSomething(), and still allow you to mock and test your code by replacing the ServiceLocator's internet collection:
ServiceLocator.Register<IService>(myFakeService);

Static method in Data Access Layer

I have used a lot of static methods in Data Access Layer (DAL) like:
public static DataTable GetClientNames()
{
return CommonDAL.GetDataTable("....");
}
But I found out that some developers don't like the idea of static method inside DAL. I just need some reason to use or not use static methods inside DAL.
Thanks
Tony
From purists' point of view, this violates all kinds of best practices (like, dependency on implementation, tight coupling, opaque dependencies, etc.). I would've said this myself, but recently I tend to move towards simpler solutions without diving too much in "enterprizey" features and buzzwords. Therefore, if it's fine with you do write code like this, if this architecture allows for fast development and is testable and, most important, solves your business problem -- its's just fine.
If I had to pick one reason not to use static methods, that would be that it limits your ability to write unit tests against your code. For example creating mocks for your DAL will be more difficult because there is not an actual interface to code against, just a bunch of static methods. This further limits you if/when you decide to adopt frameworks that require interfaces to support things like IoC, dependency injection etc.
That's Unit of Work, just static, isn't it?

Categories

Resources