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 :)
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).
Related
I'm making a game in Unity C# using a Singleton GameManager and I was warned that using references of the class in other scripts like GameManager.instance.someVar makes the code fragile and difficult for later edit. So I looked for how to access a singleton with interfaces but haven't found what I was after. As I wish to code properly, I would like someone to point me to a decent source that tells me how to do so, or have him/her tell me in brief.
Well there is a general solution to this, I am not sure how feasible it will be for you.
Suppose we have a true singleton:
public static class Highlander //cos, there can be only one. Sorry. couldn't resist
{
public static void Quicken(string name)
{
Console.WriteLine("{0} gets their quickening on",name);
}
}
Suppose we want to be able to pass this around in an abstract manner, using Interfaces.
public interface IImmortal
{
void Quicken();
}
Well, you cannot implement an interface on a static class or member, so how do you pass references to this class around by interface?
Simple - create a wrapper/adapter class which implements the interface you want:
public class McLeod: IImortal
{
public void Quicken()
{
Highlander.Quicken("Conor");
}
}
public class Kurgen: IImortal
{
public void Quicken()
{
Highlander.Quicken("The Kurgen");
}
}
Now you can pass IImortal around, and the wrapping implementation(s) simply call through to the Singleton. Note how the Wrapper can supply data to the Singleton from within itself, as above, in which case it's more like an Adapter. But the concept is the same.
In the case of Unity, I don't know if this will suit, since the GameManager class likely exposes a ton of other properties and methods you would also have to wrap/adapt - it may not be worth creating wrapper interfaces for all of this, so consider perhaps that in this case you need to embrace it :)
Singletons, being static, dont support interfaces. Perhaps your other source might mean that you should use a Factory pattern or perhaps an Inversion of Control (IOC) method. In those cases the Factory would look like GameManagerFactory.GetGameInstance() rather than refer to the Instance static property of a GameManager.
The true limitation of Singlton programming is in the area of unit testing - because your code is bound directly to the specific class "GameManager" you could not replace it in a unit test with another "test version" of the GameManager. To support unit testing you should try to make sure that any significant classes your code depends on could be replaced by a test version of a class, without your code caring. When using Singletons this is hard (if not impossible) to do.
Usually I tend to create an empty GameObject, give it a proper name or a tag and attach a script component to it.
This way I can easily get a reference in any other GameObject that might need it and retrieve the script component from it.
I have a C# class which instantiates on its own a NetworkCommunicator class. I'd like to mock out the NetworkCommunicator class for my unit test, and replace it with a pretty simple stub.
But the NetworkCommunicator is never passed as a parameter. It's created by the class being tested.
In Ruby, this is easy to mock out. In Java, this is why you need Dependency Injection, which is too heavy for this project. Is there a simple way to mock this out in C#, perhaps using Moq or something similar?
You mentioned that DI is too heavyweight for this project, why not try some Truck Driver's DI, thus:
public interface IDependency
{
void DoSomeStuff();
}
public class ClassUnderTest
{
private IDependency _dependency;
public ClassUnderTest(IDependency dependency)
{
_dependency = dependency;
}
public ClassUnderTest() : this(new Dependency())
{}
public void ImportantStuff()
{
_dependency.DoSomeStuff();
}
}
Using this constructor chaining technique, you can now mock the IDependency all you want, without worrying about hooking up DI or IoC.
Create a "TestClass" that inherits from your class under test.
Override that parameter with a mocked instance
Create a property on the class under test that returns the new instance
public class ClassUnderTest {
public string MethodYouAreTesting(int someInput) {
var networkCommunicator = GetNetworkCommunicator();
// Do some stuff that I might want to test
return "foo";
}
public virtual NetworkCommunicator GetNetworkCommunicator {
return new NetworkCommunicator();
}
}
[TestFixture]
public class ClassUnderTestTests {
public void GivenSomeCondition_MethodYouAreTesting_ReturnsFooString() {
var classToTest = new TestClassUnderTest();
var result = classToTest.MethodYouAreTesting(1);
Assert.That(result, Is.EqualTo("foo");
}
}
public class TestClassUnderTest : ClassUnderTest {
public override GetNetworkCommunicator {
return MockedNetworkCommunicator;
}
}
I read of this technique this in the "Art of Unit Testing" and use it frequently when refactoring to full DI doesn't make sense or when the class I'm testing isn't something I can change.
Hope this helps.
You should refactor your code and pass dependencies in. You can also use typemock as easier to use alternative to fakes in Visual Studio 2012.
There's the built-in Fakes system, pretty well described at http://msdn.microsoft.com/en-us/library/hh549175.aspx
If that is too heavy-weight for your use case you might find the PrivateObject class more useful.
I have a C# class which instantiates on its own a NetworkCommunicator class.
As you noticed, this is a show stopper in C# when you want to mock this thing out. Solution is simple, and depends on context/purpose of the instantiated class:
inject it as a dependency if it's reusable component
provide it via factory if it's something that should be created every time when demand comes in
Either way, you'll need DI (factory from the second example is naturally injected too).
In Java, this is why you need Dependency Injection, which is too heavy for this project.
Is dependency injection too heavy? DI is design pattern, it's only too heavy when used when it's not really needed. Your question clearly shows you need it. Perhaps you meant that DI container is too heavy for your project? This might be true, as depending on project's complexity, you should choose appropriate way to apply DI.
I'd like to raise one more point to be aware of when applying solution like the one proposed in Greg Smith's answer. Essentially, your API ends up with constructors:
public TestedClass() : this(new Dependency()) ...
public TestedClass(IDependency) ...
As appealing as it might be at first glance, when long-term perspective is taken into account, several issues start to emerge:
does TestedClass must have IDependency or can it do fine without it?
what default (parameterless constructor) defaults to (implementation detail-level knowledge is required to use it properly)?
it creates tightly coupled components (TestedClass assembly will possibly have to reference other assembly - Dependency's assembly, even though it might not be relevant to it anyhow)
This is an anti-pattern going under different names, e.g. Bastard Injection. Of course, some of those problems might be mitigated (like making constructor protected/internal or having default implementation in the same assembly), but the anti-pattern and its long-term consequences remain. Also note that it's by no means more simple, faster or less code than regular DI.
You'll have to ask yourself what's less heavy - applying proper DI, or going you ways around with anti-patterns and/or 3rd party frameworks (MS Fakes).
I just proposed the following pattern for someone else. I have used it a few times, when I wanted the ability to inject dependencies for test, but but still wanted this backdoor (somewhat) invisible to outsiders. Hence, the empty public ctor and internal ctor with the argument:
public class ClassThatUseInjection
{
private readonly SomeClass _injectedClass;
public ClassThatUseInjection(): this(new SomeClass()) {}
internal ClassThatUseInjection(SomeClass injectedClass)
{
_injectedClass = injectedClass;
}
}
public class SomeClass
{
public object SomeProperty { get; set; }
}
My idea was that since the empty ctor does nothing but forward with a new instance, my crime is not too bad. What do you think? Is is too smelly?
Regards,
Morten
I think it is ok. In fact, what you are doing with injecting the class is Dependency Injection and a practical use of the Open/Closed Principle.
I don't even see no harm in making that internal ctor into a public one.
My problem with this is always, that I don't want to force others to create an instance of the injected class, therefore, the default ctor. But if they want to create an instance, they can go ahead and do so.
On a related note: IMHO, you should use an interface instead of a class, otherwise, I don't see too much advantage in passing that class in the first place...
It's called "poor man's dependency injection", if you can't get a proper IOC container into your app its a reasonable alternative although you would be better off with the power a container gives you.
Jimmy Bogard has a good write up here
wanted this backdoor (somewhat) invisible to outsiders
Making it internal successfully does that, IMO.
The down-side is that it puts your tests in the same assembly.
See also Hide public method used to help test a .NET assembly about how to hide public methods if your tests are in an external assembly.
Edit: what you've done is especially appropriate, if SomeClass is logically internal ... if it's an implementation detail which shouldn't/needn't be exposed in the assembly's public interface.
I've used this Service Locator Pattern in my Application and implemented as a Singleton:
Service Locator Pattern
And now I want test it .So far I've written a test verifying that my class is a Singleton. I've also written this test:
[Test]
[ExpectedException(typeof(ApplicationException))]
public void GetService_Throws_Exception_When_Invalid_Key_Is_Provided()
{
locator.GetService<IRandomService>();
}
But I don't really like the last test since I'm never going to use the IRandomService. So I'm looking for a nicer way to test that the GetService<T> throws an exception. Also I like to know if there is any other relevants tests I could write for this class.
I'm using the latest version of NUnit.
Cheers
Some things:
A test to verify the class is a singleton? The singleton pattern will ensure that attempting to treat a singleton as an instance class won't even compile. If you have not written your service locator something like the following, it's wrong:
The Singleton Pattern in C#:
public class MySingleton()
{
//Could also be a readonly field, or private with a GetInstance method
public static MySingleton Instance {get; private set;}
static MySingleton()
{
Instance = new MySingleton();
}
private MySingleton() { ... }
}
...
//in external code
var mySingletonInstanceRef = MySingleTon.Instance; //right
var mySingletonInstanceRef = new MySingleton(); //does not compile
//EDIT: The thread-safe lazy-loaded singleton
public class MySingleton()
{
//static fields with initializers are initialized on first reference, so this behaves lazily
public static readonly MySingleton instance = new MySingleton();
//instead of the below you could make the field public, or have a GetInstance() method
public static MySingleton Instance {get{return instance;}
private MySingleton() { ... }
}
The service locator is an anti-pattern. It sounds great, but it doesn't really solve the problems that it was created to solve. The chief problem is that it tightly couples you to the service locator; if the locator changes, every class that uses it changes. By contrast, Dependency Injection can be done without a fancy framework; you just make sure any complex, expensive, reusable, etc. object is passed in to the object that needs it via its constructor. DI/IoC frameworks just streamline this process by ensuring that all known dependencies of a required object are provided, even if an object in the graph can't know about dependencies of its children.
You have already developed the class. The spirit of TDD/BDD is that you write tests that will prove that code you haven't yet written will be correct. I'm not saying writing tests now wouldn't serve a purpose, but a failing test requires the object be opened up and fixed, and if the code is already integrated you could break other things.
Unit tests make heavy use of constructs that will never see production. Mocks, stubs, proxies and other "test helpers" exist to isolate the object under test from the environment into which it is normally integrated, guaranteeing that if the inputs are A, B, and C, the object under test will do X, regardless of whether what it normally hooks into will give it A, B, and C. Therefore, don't worry about creating simple constructs like a skeleton interface that you wouldn't use in production; as long as it is a good representation of the input you would expect in the test case, it's fine.
But I don't really like the last test since I'm never going to use the IRandomService.
But that's kind of the point. You wire up your locator in the test setup method (arrange), and then you lookup a key that was not wired up (act), then you check that an exception was thrown (assert). You don't need to use types you're actually going to use, you just want to get some confidence that your method is working.
Also I like to know if there is any other relevants tests I could write for this class.
Well, I'm going to answer a different question here.
Is the service locator pattern evil?
Yes, it is pure evil.
It defeats the purpose of dependency injection because it doesn't make dependencies explicit (any class can pull anything out of the service locator). Moreover, it makes your all of your components dependent on this one class.
It makes maintenance an unbelievable nightmare because now you have this one component that is just spread all over your codebase. You have become tightly coupled to this one class.
Further, testing is a nightmare. Let's say you have
public class Foo {
public Foo() { // }
public string Bar() { // }
}
and you want to test Foo.Bar.
public void BarDoesSomething() {
var foo = new Foo();
Assert.Equal("Something", foo.Bar());
}
and you run your test and you get an exception
ServiceLocator could not resolve component Frob.
What? Oh that's because your constructor looks like this:
public Foo() {
this.frob = ServiceLocator.GetService<Frob>();
}
And on and on.
avoid, Avoid, AVOID.
I don't quite understand your question. Are you dissatisfied with requesting a type that you'll never use in production? Are you dissatisfied with using the service locator in a fashion that is not indicative of production code? The test itself looks ok to me -- you're requesting something that doesn't exist and proving that the expected behaviour occurs. For a unit test, such a thing is perfectly reasonable to do.
One thing we did when using a dependency injection container was to separate our application wiring phase into modules, then we'd try and resolve the root type in an integration test to ensure that the app could be wired up. If the wiring test failed, it was a good sign that the app wasn't working (though it didn't prove that the app worked, either). It'd be tricker to do this sort of thing when using a service locator.
I agree 100% with Jason, too -- service locators seem like a good idea, but quickly turn nasty. They 'pull' (types using the service locator instance must be coupled to it), whereas Dependency Injection containers 'push' (the vast majority of the application is DI agnostic, so the code is far less brittle and more re-usable).
A couple of other things:
[ExpectedException] is deprecated.
use Assert.Throws
instead
ApplicationException is
also deprecated.
How can I write a unit test for a method that has a using statement?
For example let assume that I have a method Foo.
public bool Foo()
{
using (IMyDisposableClass client = new MyDisposableClass())
{
return client.SomeOtherMethod();
}
}
How can I test something like the code above?
Sometimes I choose not to use using statement and Dispose() an object manually. I hope that someone will show me a trick I can use.
If you construct the IMyDisposableClass using a factory (injected into the parent class) rather than using the new keyword, you can mock the IMyDisposable and do a verify on the dispose method call.
public bool Foo()
{
using (IMyDisposableClass client = _myDisposableClassFactory.Create())
{
return client.SomeOtherMethod();
}
}
If you already have your code and are asking how to test it, then you're not writing your tests first...so aren't really doing TDD.
However, what you have here is a dependency. So the TDD approach would be to use Dependency Injection. This can be made easier using an IoC container like Unity.
When doing TDD "properly", your thought processes should run as follows in this sort of scenario:
I need to do a Foo
For this I will rely on an external dependency that will implement an interface (new or pre-existing) of IMyDisposableClass
Therefore I will inject an IMyDisposableClass into the class in which Foo is declared via its constructor
Then you would write one (or more) tests that fail, and only then would you be at the point where you were writing the Foo function body, and determine whether you needed to use a using block.
In reality you might well know that yes, you will use a using block. But part of the point of TDD is that you don't need to worry about that until you've proven (via tests) that you do need to use an object that requires this.
Once you've determined that you need to use a using block you would then want to write a test that fails - for example using something like Rhino Mocks to set an expectation that Dispose will get called on a mock object that implements IMyDisposableClass.
For example (using Rhino Mocks to mock IMyDisposableClass).
[TestFixture]
public class When_calling_Foo
{
[Test]
public void Should_call_Dispose()
{
IMyDisposableClass disposable = MockRepository
.GenerateMock<IMyDisposableClass>();
Stuff stuff = new Stuff(disposable);
stuff.Foo();
disposable.AssertWasCalled(x => x.Dispose());
}
}
Class in which your Foo function exists, with IMyDisposableClass injected as a dependency:
public class Stuff
{
private readonly IMyDisposableClass _client;
public Stuff(IMyDisposableClass client)
{
_client = client;
}
public bool Foo()
{
using (_client)
{
return _client.SomeOtherMethod();
}
}
}
And the interface IMyDisposableClass
public interface IMyDisposableClass : IDisposable
{
bool SomeOtherMethod();
}
Your question doesn't make sense. If you are using TDD, then you should already have a test for what you have written. Requirements, then tests, then design, then development. Either your code passes your tests, or it doesn't.
Now, if your question is how to unit test the above piece of code, then that's another question completely, and I think the other posters have answered it up there.
Sometimes I think there are more buzzwords than developers :)
Wrapper methods like that aren't unit-testable, because you can't specify the relevant preconditions or post-conditions.
To make the method testable, you'll have to pass an IMyDisposableClass instance into the method or into the class hosting Foo (and make the host class itself implement IDisposable), so you can use a test double instead of the real thing to verify any interactions with it.
Your question doesn't make sense. If you are doing TDD, then the method that you posted is already fully tested, otherwise it couldn't even exist in the first place. So, your question doesn't make sense.
If, on the other hand, the method that you posted does already exist, but isn't fully tested, then you aren't doing TDD anyway, and your question about TDD doesn't make sense, either.
In TDD, it is simply impossible for untested code to exist. Period.
You could also change the method signature to allow passing in a mock for unit testing. This would provide an alternative to using a factory, which would also need to be unit tested. DI into the method as opposed to the class constructor may be preferable here.
public bool Foo(IMyDisposableClass mock = null)
{
using (IMyDisposableClass client = mock ?? new MyDisposableClass())
{
return client.SomeOtherMethod();
}
}
If you are testing Foo, then you should be looking at the output of Foo, not worrying about the disposal of the class it is using internally.
If you want to test MyDisposableClass' dispose method to see if it is working, that should be a separate unit test built against MyDisposableClass.
You don't need to unit test the using { } block, since that is part of the language. You either trust that it's working, or don't use C#. :) I don't see the need to write a unit test to verify that Dispose() is being called.
Without a specification for Foo, how can we say how to test it?
Get the specification for Foo.
Write tests to ensure that it meets all specifications and requirements (or a reasonable subset- some functions could require practically infinite amounts of data to test).
I believe you have a second, implicit question in there - which is how to test that use of your MyDisposableClass correctly Disposes of the object when it is freed by exiting an using clause. This is a separate test issue, and shouldn't be combined with the test of Foo, since the specification of Foo shouldn't reference implementation specific details such as the use of your MyDisposabeClass.
I think the other posters have answered this question, so I won't further elaborate.