Reputation: 569
Don't have much experience with testing, trying to change that by testing libraries I've made recently.
Using nunit with nsubstitute for this.
So the situation I have is a class like this:
class MyClassToTest {
private ISomeOtherClass MyPrivateClass { get;set }
public MyClassToTest() {
MyPrivateClass = new SomeOtherClass();
}
public void DoSomething() {
MyPrivateClass.SayHello();
}
}
Now, a test for the DoSomething
method would be to see if the method SayHello()
was actually called on the ISomeOtherClass
instance.
The problem is that it's private, when looking up the best way to test this, the only thing that came up was to make the property internal and set the InternalsVisibleToAttribute
to the assembly the tests are in.
While this solution works and the external interface for my library is still ok, the correct accessor for this property in the context of the library would still be private.
The test I'd write is after making it interal:
public void MyTest() {
var objPrivateClass = Substitute.For<ISomeOtherClass>();
var obj = new MyClassToTest();
obj.MyPrivateClass = objPrivateClass;
obj.DoSomething();
objPrivateClass.Received().SayHello();
}
Is there a better way to test this without me having to modify my original code to make it testable?
It might be setting InternalsVisibleToAttribute and making the property internal is the correct thing here, but a couple of hours ago I didn't know about the existence of InternalsVisibleToAttribute
so thought it best to ask :)
Upvotes: 1
Views: 2840
Reputation: 1092
To answer the exact question, You can use reflection to reach private members, but that is a fragile and rather slow solution.
The best advice I can give you is that private things should stay private; test an object's behavior through its public interface. So if is too big and hard to test, just refactor it to be testable. Think of the Single Responsibility Principle and the Inversion of Control principles.
Edit 1.: You are probably looking for the concept of Dependency Injection. This should be alright most of the times; however when we talk about highly reusable libraries (you mentioned you are making a lib), other solutions may fit better for the users of your library (e.g. creating a Facade or rethinking your design).
Upvotes: 4