Reputation: 749
I'm currently working on a bigger C#-Project. I've written several classes that connect to a database layer and now have to test them. The testing framework used is the Visual Studio Ultimate one. I've been given a Mock-layer for testing, however I'm unsure how to use it.
Basically my methods work like this:
public static void bla()
{
//This is a multithreaded singleton
Connection con = Connection.Instance;
//This raises a lot of Events
con.SomeConnection.Send(new GetBla());
}
With the MockLayer basically being ConnectionMock and implementing all it's methods as a mock. Is there any way to make con being the Mock WITHOUT changing the methods in any way?
Upvotes: 1
Views: 3067
Reputation: 935
Actually you can mock singletons using reflection. See my answer to:
How to Mock a Static Singleton?
Upvotes: 3
Reputation: 21365
The first step is to identify what you want to do... and most important determine your SUT (Subject Under Test)
Is there any way to make con being the Mock WITHOUT changing the methods in any way?
I do not think you can do something like that and even if you could find a technical way to do it, it wouldn't be recommended. Instead you should have an abstraction of your DAL layer using a repository for example. Something like this:
interface IMyRepository
{
void Send(Bla bla);
}
And now you could use DI in your classes to inject a reference to this interface. When you want to write unit tests you should create a mock of the interface.
In order to create mocks easily I can recommend you the following tools:
Anyway in your case, the only way to test your code without changing your code would be changing the connection string to a dummy database, and run integration tests
Sadly I have to tell you that your code is not test-friendly, you should refactor your code to remove the static members.
The best tip I can tell you is: Read guidelines about writing clean test-friendly code.
Take a look at the following links:
It is good that you are interested in writing tests for your code, but since you didn't take a TDD, which means writing your tests first, you wrote your code without testability in mind, and the consequence is simple: writing tests will be a real PITA and writing them will require to refactor your code.
I understand you do not want to refactor your code, because you do not want to break existing functionality, and that's one of the greatest benefits of writing tests from the beginning, you would be able to refactor your code and run your tests to be sure you did not break anything
Upvotes: 2
Reputation: 3302
In short, no, there is no way. This is one of the biggest downsides of using static classes and singleton objects. You have defined a rule that only one Connection object can ever exist, and it always has to be the exact instance you have specified. Creating a mock and trying to get all of your code to use it would be a violation of that rule.
In other words, in order to mock an object, you have to be able to create another instance and substitute your instance for the expected one. Static classes (and singletons) explicitly prevent that from being possible.
A better option is to use dependency injection, so that your "expected" Connection class is always registered in a real environment, and your mock is always registered for unit tests.
Upvotes: 1