Context. I have interface IVehicle, class VehiclesFactory and private class Vehicle nested in the VehiclesFactory. Thus all code except the VehiclesFactory kwnows nothing about any implementations of the IVehicle.
Question. How should I unit test the Vehicle? And should I do it at all?
Assumption 1. I can make the Vehicle public. However this will allow the all code to write new VehiclesFactory.Vehicle(...) which I try to avoid.
Assumption 2. I can make a new public method in the VehiclesFactory, e. g., IVehicle ForUnitTests_Vehicle(...) which just calls the Vehicle constructor and passes its arguments to that constructor (allowing a unit test to supply necessary mocks). However this will allow the all code to call this strange method.
Assumption 3. Factories is a plague; use the new operator everywhere. However this will couple my code more tightly.
How should I unit test the Vehicle?
You can use reflection to create an instance of Vehicle class in your test project or make your Vehicle class internal and use InternalsVisibleToAttribute attribute to make it visible to your test project. Though switching from private to internal will make your class visible to all the code in the same project, so I'm not sure if it's acceptable for you.
And should I do it at all?
Up to you, if it contains application critical logic probably you should test it.
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.
Using C#
I know this has been asked before and a lot of people will answer no, only test public methods, not implementation details. Others will say yes, if it has some important logic. Although you might then consider breaking it off into its own class.
One issue I haven't seen addressed is having to repeat testing public methods that call protected methods in inherited classes.
If I test the protected method in the base class, surely I don't have to retest it in base classes. Or should I copy and paste the tests to multiple classes?
You definitely should test protected methods. From a testing standpoint, a "protected" method still is part of the public interface, even though the "public" is limited to those classes that derive from your class. Because code that you do not control can reference those methods, you must ensure that they function as defined.
As for repetitive testing, I don't have a definitive answer. If given:
public class A
{
protected virtual void Foo() {}
}
public class B:A
{
}
The question is whether you write a test for B.Foo. On one hand I would say no, because B doesn't provide an explicit implementation of Foo, and so its behavior can't possibly be different than the behavior of A.Foo, and we can assume that you've already tested A.Foo.
On the other hand, A.Foo could depend on some other protected fields or properties that B could modify, or on a private callback that B provides in a constructor or initialization function. In that case, then you absolutely must test B.Foo because its behavior could be different than A.Foo, even though B doesn't override A.Foo.
Obviously, if B overrides Foo, then you have to write a test for B.Foo. But if B doesn't override A.Foo, then you have to use your judgement.
All that said, it's really no different from having to write tests for any class that derives from another. Consider deriving a class from TextWriter. Would you write explicit unit tests for all of the virtual functions defined by the TextWriter class? Or would you write tests only for those methods that you override, and those methods whose functionality might have changed as a side effect?
There is a lot of opinions on what should be Unit Tested and what should not.
My personal belief is that for every function you write, you should have written a unit test first to specify the desired behavior. You then write your code to make this test pass. This is applicable for private, public, protected and internal. If it is used it should be unit tested.
Believe me this makes your life easier in the long run because if you or another developer changes existing unit tested code then a change in behavior is a lot more likely to be caught.
In the real world though it usually ends up being code first then test. However they should still be written for all access levels.
I would like to do a unit test to a function that has a call to the base class inside it implementation (using .base() )
I cannot use Mocking as this is inheritance we dealing with, so I don't get the object in my constructor.
Example code:
protected override BuyerDeal Map(BuyerDealDTO buyerDealDTO, BuyerDeal buyerDealEntity)
{
buyerDealEntity.prop1 = buyerDealDTO.prop2;
base.Map(buyerDealDTO, buyerDealEntity);
return buyerDealEntity;
}
I would like to test this function but I don't want this:
base.Map(buyerDealDTO, buyerDealEntity);
to occur, as I test the base by itself.
Yet i do want to test ( Verify ) the call, and solely, the call to the base .
btw, the base class is abstract.
The problem is that if there is few classes that inherit from that base class this will result in testing the base class more than once .
Without knowing much about your mapper there might be several ways to do that:
Split your code and the map code into separate methods, e.g:
protected override BuyerDeal Map(BuyerDealDTO buyerDealDTO, BuyerDeal buyerDealEntity)
{
ExtraLogic(...);
base.Map(buyerDealDTO, buyerDealEntity);
return buyerDealEntity;
}
protected void ExtraLogic(...)
{
buyerDealEntity.prop1 = buyerDealDTO.prop2;
}
then you can test ExtraLogic. This might not work for all code as calling base may be required as a dependency, which changes the flow, as stated by comments.
I generally would not recommend that.
Or don't inherit from the base class. Inherit from the Interface and mock your abstract class then. Favour composition over inheritance (FCoI).
This allows you to inject the base class and test your code only.
Might not work if no interface is defined (which is bad anyway) or if the framework uses the abstract class explicitly.
I see three approaches:
Try to ignore the base class in derived classes' tests. Problem here is that your tests are incomplete, because you never test the interaction of derived classes' code with the base class.
Parallel inheritance hierarchies for test fixtures, i.e. an abstract fixture for the base class, which is inherited by all fixtures for derived classes. This helps to remove duplication and tests the above mentioned interaction, but makes the fixtures hard to understand.
Follow Composition over Inheritance whenever possible. No base classes, no headaches.
I would suggest to follow the third one, especially as it looks as if the mapping between buyer deals might be considered a separate responsibility anyway.
Bottom line: Just create a BuyerDealMapper, test that, and mock it when you test the other classes.
When unit testing, you are in fact testing that the code under test gives the correct output for the corresponding input.
This input may come in the form of dependencies, such as method parameters, data read from the file system or from a network source.
The output may come in the form of a value returned from the method, data written to the file system or properties passed into another class for instance.
As long as your input produces the expected output, within reason, anything else that happens in that code under test does not matter.
In your posted code, your unit test should not care whether or not the call to base.Map(buyerDealDTO, buyerDealEntity); is made or not - just that the code under test gives the expected output.
If perhaps your base class itself requires dependencies, such as file system writes or network reads etc..., these can be mocked in your test start up routines.
If you are worried that you are testing the base class multiple times, this is actually a very good thing! The more times code is tested, the more conditions and situations a piece of code sees, the more thorough, the more bullet-proof that piece of code will be. Your unit test should help guarantee that your base class code and cope with your inherited classes use of it.
For instance, how will your method cope if the base class throws an exception? Returns an unexpected value? Doesn't return for one reason or another? Unit testing should take these things into account.
Of course, if the base class call has no relevance to the method and how it works, then perhaps it shouldn't be called in that method at all. Some code refactoring may be required to fix this. This, in fact, is a huge benefit of unit testing as it can also help you with architectural issues such as this. Of course, assuming you are using TDD - rather than testing pre-written code - this can be a big help.
Refactoring
A potential way of refactoring this code is to not call the base class method in your overriden method. Have the base class ensure this method is called itself, and then in the overridden code call the code that is required. For instance:
public abstract class MyBaseClass
{
public BuyerDeal Map(BuyerDealDTO buyerDealDTO, BuyerDeal buyerDealEntity)
{
// perform base class logic here
var entity = this.MapInternal(buyerDealDTO, buyerDealEntity);
return entity;
}
protected abstract BuyerDeal MapInternal(BuyerDealDTO buyerDealDTO, BuyerDeal buyerDealEntity);
}
public class MyClass : MyBaseClass
{
protected override BuyerDeal MapInternal(BuyerDealDTO buyerDealDTO, BuyerDeal buyerDealEntity)
{
buyerDealEntity.prop1 = buyerDealDTO.prop2;
return buyerDealEntity;
}
}
Using this method, when you unit test MyClass, you are no longer testing MyBaseClass::Map(...) multiple times. Of course, you would still need to test MyBaseClass itself separately.
Ok so i just got an assignment where i have to perform unit testing on a class with a private constructor.
Now how am i suppose to do unit testing without initializing a class when all the methods are also non static.
Is there any way i can do unit testing(without reflection)on a class with a private constructor ?
If you cannot make the class public, you can still test it easily by creating an instance of it this way:
var anInstance = (YourPrivateClass)Activator.CreateInstance(typeof(YourPrivateClass), true);
This will give you an instance of your class that you can then populate.
Another helpful testing bit is if you have internal methods (not private), you can access them by making internals visible to your test class. You add this line in assemblyinfo.cs of the class with the internal methods:
[assembly: InternalsVisibleTo("YourSolution.Tests")]
If this class has a private constructor, is this to be used publicly? If not, it may be best not to unit test it. If this is the case, the code that is public should test this code in itself by calling it.
Unit testing is there to test what is to be used by the public - by interfacing code in between application layers for instance. Take an input, I want this output. That is really what unit testing is about. Unit testing doesn't care what is in the actual method. As long as it returns what you want, performs the desired action, you have a pass.
You should be testing through a public API -- there must be some way that the class you want to test is instantiated and used.
Unit tests are typically written and run to ensure that code meets its design and behaves as intended.
Creating a non-static class on which you cannot create an instance i.e. private constructor(s) only, might never be useful, in otherwords its is never Unit Testable.
In order to be Unit testable:
You should be able to create an instance of the class.
Testable Function should be either Public or Internal.
You could test Internal function by making your assembly as a Friend Assembly
It might be a singleton and you don't want the public constructor for the class.
Decorate the constructor with:
[ExcludeFromCodeCoverage]
In our Core domain model design, we have got a class called "Category" whose constructor is internal by design. Since the constructor is internal, when writing unit test cases I won't be able to create the object of "Category".
So my question, is it a best practice to make the constructor public just for making the "Category" class testable? Or I shouldn't be testing that "Category", instead I should have tested the Class/method responsible for creating this object?
Ta,
Rajeesh
Don't make the constructor public only for the sake of unit tests. If from a design point you decided that it should be internal, leave it that way. Test the classes that invoke this constructor.
In .NET there's the InternalsVisibleToAttribute which allows you to expose internal members to unit tests.
TDD means Test-Driven Design, and a corrolary to this is that a constructor can't really be internal "by design" if you can't test it.
Consider why it's internal. This will tell you how to address the issue. You shouldn't make the constructor public just to be able to test it, but you should consider a design that makes it easy to create new instances.
Often, constructors are made internal to protect invariants, but you could just as well achieve the same goal with a public constructor that takes required input as constructor parameters.
public class MyClass
{
private readonly string requiredString;
public MyClass(string requiredString)
{
if (requiredString == null)
{
throw new ArgumentNullException("requiredString");
}
this.requiredString = requiredString;
}
}
Notice how the combination of the Guard Clause and the readonly keyword protects the invariant of the class. This is often a good alternative to internal constructors.
Another reason for having internal constructors is when you have a Factory Method that may return a polymorphic object, but once again, consider if it would be a problem to expose the constructor if it doesn't mean compromising invariants.
The beauty of TDD is that it forces us to take a good look at any design decision and be able to really justify each and every one of them. Consider the justification of making the constructor internal and then modfiy the API so that the type is easy to create.
Add
[assembly: InternalsVisibleTo("UnitTestAssembly")]
to your AssemblyInfo.cs. Then UnitTestAssembl.dll is able to call your internal methods. More info is available here.
You could consider creating a static factory method that is named
Category *ConstructCategory_ForUnitTest();
with which you can create the object just for the sake of testing it.
It is apparent from the name that it should not be used outside testing context, and code review can easily spot the 'illegal' use in production grade code.