Unit Testing - best practice - c#

I use Visual Studio 2010 Professional with MSTest framework to perform unit tests. I have nasty production code to test. First issue is that problematic code is in constructor. I will show examaple :
class ClassToTest
{
public SomeEnum UpperBorder;
public SomeEnum LowerBorder;
public int var1;
private readonly SomeEnum2 _ethnicGroup;
private readonly double _age;
public int DataStart;
public int DataEnd;
public double[] DarkRedDarkYellow;
public double[] DarkYellowGreen;
public double[] GreenLightYellow;
public double[] LightYellowLightRed;
public ClassToTest(SomeEnum upperBorder, SomeEnum lowerBorder, int var1, SomeEnum2 ethnicGroup, int age)
{
UpperBorder = upperBorder;
LowerBorder = lowerBorder;
BscanIndex = bscanIndex;
_ethnicGroup = ethnicGroup;
_age = age;
DataStart = 0;
DataEnd = 0;
DarkRedDarkYellow = null;
DarkYellowGreen = null;
GreenLightYellow = null;
LightYellowLightRed = null;
}
}
My question are :
write one test with assert statement for each variable? or write couple of tests and in each test check only one variable at once? for example :
[TestMethod()]
public void ClassToTest_Constructor_upperBorder_PTest()
{
//ACT
var ob = new ClassToTest(SomeEnum.bor1, SomeEnum.bor2,10,SomeEnum2.Asian,10);
//ASSERT
Assert.IsNotNull(object);
Assert.AreEqual(ob.upperBorder,SomeEnum.bor1);
}
Should I check if constructor properly assign parameters to private field? Or if there will be property which returns that private field but it performs some another action like triggers event, log action etc.
I cannot find any information about it. So your advice will be most precious.

I would have written one test with many asserts. I know that some people argue against it, but I think that testing one method and validating all relevant postconditions for that method is ok in one test. Otherwise you'll have tons of test methods.
Private fields are normally not tested by unit tests. A unit test should preferrably test externally visible behaviour and state.
I think that a good rule is to strive for as full code coverage as possible for the unit tests. If there is an error in the constructor and the assignments to field, that should be caught in other more high-level tests if they have proper coverage. The only reason I see to write tests for private parts of a class is if it is very hard to trigger certain scenarios, such as error handling routines otherwise. When dealing with threads there can also be reasons to acquire certain private locks before executing a test, to emulate specific scheduling scenarios.

Write one test with assert statement for each variable gets my vote:
You are testing that the constructor correctly assigns the values given to it.
If you had multiple constructors, with different numbers of parameters, then I'd advocate writing a separate test for each constructor.
If the constructor also sets private fields, then you could also test these - some people don't like checking private members in unit-tests. Indeed, with well-designed code this should not be necessary.
However. personally I often find that, with legacy code that was not designed with Unit Testing in mind, occasionally testing private members can be the easiest way to achieve good test coverage.
Check out this article for an easy way to achieve this.

The best solution I've found for such issues is to:
Move your construction code into a protected initializer method, which is called from the constructor. Keep your constructor with the same parameters, and don't create a default (no parameters) constructor.
For your test, create an inherited testable version, which should have the following:
a default constructor, which does nothing (not even call the initializer)
a public overload of the protected initializer
public exposed properties of any private/protected values you want to verify
At that point, you can test the initializer like any other method. If all your initializer is doing is stuffing values into member variables, a single test, asserting all the values is sufficient; but if your initializer has any conditional logic, make sure to write adequate tests to exercise that logic.

There are some major points that are needed to be considered while writing unit tests as shown
Separate project for unit testing.
One class for writing unit tests of functions in one class of main code.
Covering conditions within functions
Test Driven development (TDD)
If you really want to know more (with examples), have a look at this tutorial
Unit Tests c# - best practices
https://www.youtube.com/watch?v=grf4L3AKSrs

Related

How would I refactor out a static method so I can test my method?

I know I can't use Moq to mock out a static method call inside my method under test, so what would I need to do to refactor the method so I can test it? I also have a method calling the base class method, would I need to refactor that and if so how? I don't want to use MS.Fakes or TypeMocks and create a shim, I would rather refactor and write solid code!
public override DateTime ResolveDate(ISeries comparisonSeries, DateTime targetDate)
{
if (comparisonSeries == null)
{
throw new ArgumentNullException("comparisonSeries");
}
switch (comparisonSeries.Key)
{
case SeriesKey.R1:
case SeriesKey.R2:
case SeriesKey.R3:
case SeriesKey.R4:
case SeriesKey.R5:
return DateHelper.PreviousOrCurrentQuarterEnd(targetDate);
}
return base.ResolveDate(comparisonSeries, targetDate);
}
[TestMethod]
public void SomeTestMethod()
{
var mockIAppCache = new Mock<IAppCache>();
var mockISeries = new Mock<ISeries>();
ReportFR2 report = new ReportFR2(SeriesKey.FR2, mockIAppCache);
DateTime resolvedDate = report.ResolveDate(mockISeries, DateTime.Now);
//Assert.AreEqual("something", "something");
}
Looking at the above, you have three basic conditions you can test:
When Comparison Series is null
When the Comparison series key is R1:R5
When the Comparison series key is not null and anything but R1 : R5
In condition 1, you can cover this with a test pretty easily.
In condition 2, When it's R1:R5, that is where it appears it hits your static method.
From the perspective of your ResolveDate method, you still care what the value is when it hits this branch.
It would be nice to be able to prove that R1:R5 call the static helper, but as mentioned in the comments, the only way to cleanly do that is to wrap your DateHelper with an interface and pass that to the constructor of this class. That may not be worth the effort.
If you decide not to do that, I suggest that you still give a test that falls into that branch, and then also write another set of tests that targets your DateHelper.PreviousOrCurrentQuarterEnd() function directly, hitting all the edge cases. This will help isolate which code is the culprit if something fails.
The same can be said for condition 3 as condition 2. Although it's in your base class, it's still a valid logic branch.
Again, you will have a hard time proving that it called your base class,
But it is still valid to check the outcome.
So, I think you have four sets of tests you can write to start out, and then after you have these passing, you can decide if you want to take on refactoring your utility class DateHelper. My guess is you'll say no :-D
Given a ReportRF2 class and a null Comparison series
When calling report.ResolveDate
It should throw a Null reference exception. Use
`Assert.Throws( () => report.ResolveDate( null, DateTime.Now ));
Given a ReportRF2 class and a series key in the set of R1:R5
When Resolving the Date for boundary X (such as 1/1/0001), it should equal y;
When ".." for ..., ...; (repeat for your edge/boundary cases; consider using Data Driven)
Given the ReportRF2 class and a series key NOT in the set of R1:R5 and NOT NULL
when Resolving the Date for boundary X, ... similar to #2 but probably different expected results.
Given the static utility class DateHelper
when calculating the PreviousOrCurrentQuarterEnd() and the date is X, it should equal y,
similar to edge cases in #2 above.
That will then give you coverage of the expected results, and tells you failures are stemming from your ResolveDate method or your DateHelper.PreviousOrCurrentQuarterEnd() method. It may not isolate as much as a purist would like, but as long as you cover your edge cases and your happy paths, it proves your app is functioning as planned (as long as those tests are passing).
What it does not really let you do is assert that a specific behavior is taken, other than when the comparison series is null, so it's up to you to decide if you need that verification. But, you should still have proof that when certain values or ranges go in, you get predictable outputs, and that adds some value.
Just to add to #Damon's nice answer, wrapping the DateHelper with an interface can be done quite easily:
public interface IDateHelper
{
DateTime PreviousOrCurrentQuarterEnd(DateTime targetDate);
}
As noted, you'll need an instance class that implements this interface, but only for your production code, since unit tests will just use a Mock<IDateHelper:
public class InstanceDateHelper : IDateHelper
{
public DateTime PreviousOrCurrentQuarterEnd(DateTime targetDate)
{
return DateTimeHelper.PreviousOrCurrentQuarterEnd(targetDate);
}
}
VoilĂ , you can now mock the IDateHelper interface and you have an implementation that uses the existing static code.
I've used this wrapping technique for writing unit tests on a method that launches a new Process, so I could test the method without actually launching a full-fledged process when all I needed to know was whether the method under test would call .Start(StartInfo), without the side-effects.
Picture this method:
public bool StartProcessAndWaitForExit(ProcessStartInfo info)
{
var process = Process.Start(info); // test-hindering static method call
//...
}
The only change I had to make was this:
public bool StartProcessAndWaitForExit(IProcessWrapper process, ProcessStartInfo info)
{
var process = process.Start(info); // injected wrapper interface makes method testable
//...
}
If ResolveDate is the only method in your class that requires an IDateHelper, injecting it as a method parameter is fine; if you have a bunch of methods that would all need it as well, injecting it as a constructor argument and making a private readonly IDateHelper _helper; field (initialized in the constructor) is the best way to go.

C# Unit testing class with a private constructor?

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]

Mocking a private field

I know a similar question has been asked but I have not found a clear solution. I'm trying to mock a private field from a large class. The private field gets instantiated in some earlier method and I'm trying to unit test a latter method which references the field.
So I have an earlier method in my class:
public bool validateAll(ref DataEntry[] oEntries, string sMediaPlanId, ITemplateGenerator oTempGen)
{
...
// private field that I am trying to mock
this._sMediaPlanObjective = (MPWrapper.Instance).getMediaPlanObjective(sMediaPlanId);
...
}
And I'm trying to Unit test a method that references the private field:
public bool validateFlightObjective(ref MPDataEntry oEntry)
{
...
string entryFlightObjective = oEntry.getFlightObjective();
string mediaPlanObjective = this._sMediaPlanObjective;
if (entryFlightObjective != mediaPlanObjective)
{
return false;
}
...
return true;
}
Given that I have a large class and this is just one method I want to test, is there a possible way to just mock this private field? Am I missing something basic or should I consider some other approach?
You can't mock anything that's private, static, or essentially - non overridable (this comes as a free mocking libraries limitation).
What you usually do in such situations (when it appears that private member has to be tested), is extracting your private member to a separate class and inject it to tested class as a dependency.
In your case, you actually need to extract code that creates _sMediaPlanObjective, which is this line:
this._sMediaPlanObjective =
(MPWrapper.Instance).getMediaPlanObjective(sMediaPlanId);
Object that provides getMediaPlanObjective method should be injected to your tested class. If you do so, you can simply mock that object and tell it to return mocked version of _sMediaPlanObjective.
You can use JustMock framework.
For example:
double value = 0;
var fakeFilterSetHelper = Mock.Create<FilterSetHelper>(Behavior.CallOriginal);
Mock.NonPublic.Arrange<double>(fakeFilterSetHelper, memberName: "GetPriceRangeFromSession").Returns(value);
There is no reason to have any kind of tests on private fields.
using an object you can reference to the public methods as the object API.
the object itself can have it's changing state according to the operation you perform on it - but it will be reflected in other public methods / access to DAL (DB / Registry / File/ any other resource that is not in memory)
So in your case you can have a unit tests like that:
call the method that initializes the private field as you expect it to and -
Call validateFlightObjective with a parameter that you know that have to return false according to the _sMediaPlanObjective "wanted to be state", and verify that the result is false.
Call validateFlightObjective with a parameter that you know that have to return true according to the _sMediaPlanObjective "wanted to be state", and verify that the result is true.
If you see that it is hard to test this object, then that might be a "smell" - maybe you have more than one responsibility there and you should start refactoring and split the class to smaller classes which will be easier to test
That it a bit long but i hope it was helpful

Testing working of internal functions using nunit tests

I have a function which calls many functions internally. I see in tutorials that test methods are designed in such a way that only the return values of outer functions are checked. How can I check the values returned by internal functions.
Only the GetValues() methods values are tested. How can i check the working of other methods inside GetValues(). How can I check its working using unit testing?
[TestFixture]
public class Class1
{
[Test]
public void Tester()
{
TesterClass clasObj;
int a = clasObj.GetValues();
Assert.AreEqual(10,a);
}
}
How can i check its working using unit testing?
In unit tests you only care about the, well, the unit, under test. In this case it is the GetValues. Also, usually only the public methods are unit tested. Because it is only the public methods ( interface) that has to be tested and not the internal workings.
It also ensures that the tests are not brittle. If you change the way a private / internal method works, but will essentially make the public interfaces work the same ( this especially when you are using mocks, and not really in the kind of testing you are doing), you shouldn't really be facing failed unit tests.
In such cases, you should be making sure that your unit tests cover all code path through the public method being tested and the private / internal methods that are being called by the method under test.
Sometimes, you do want to test the internals and one way is to use the InternalsVisibleToAttribute and mark the test assembly as a "friend".
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx
Another way is to subclass the class you are testing ( possibly in your test assembly), and add a public wrapper method to the method to be tested and use this proxy class and the public wrapper for testing.
I think you can do this with some tools, like TypeMock, but there is a reason why most tools don't allow it. This is because it usually makes the tests very brittle, meaning that when you change the internal code of a class, the tests will break. Internal members should be encapsulated and that is a good thing. I would look at a design that is testable from its public interface.
Generally you want to avoid testing the internal implementations of code, this is so that you can refactor and not break any tests. However, if you want to test the inside of another object, then the answer is easy. By wanting to test private implementation, the code smell is that the current object under test is doing too much work. In turn violating such rules as the single responsibility principle.
Therefore split out GetValues into a new object that you can test, such as:
ExampleFormatter.FormatValues()
Now this would be a public class with a public method meaning you can easily test it. All GetValues has to do now is invoke FormatValues with the correct params. You could use a mock object to verify that this happens as expected. As this is now public, when can test such things as the formatting of the values are as we expect and so forth. Any time you find it hard to test some code it usually means the code is doing too much, break it out!

Making methods 'internal' to remove dependencies (for unit tests) - a good practice? Any better way?

I have a class as follows.
public class MyClass
{
public MyMethod()
{
int x = CalculateSomething();
}
private int CalculateSomething()
{
// Do something and return an int
return 100;
}
}
To unit test this I added [assembly: InternalsVisibleTo("MyTests")] and changed the private method to be internal virtual.
In the unit test project I created a class MockMyClass and created private method as follows.
public class MockMyClass : MyClass
{
public bool MadeHappyNoise {get; set;}
internal override int CalculateSomething()
{
MadeHappyNoise = true;
return base.CalculateSomething();
}
}
The unit test is now as follows
[TestMethod()]
public void WasCalculateSomethingCalledOK()
{
MockMyClass mk = new MockMyClass();
mk.MyMethod();
Assert.IsTrue(mk.MadeHappyNoise, "Oops...CalculateSomething not called...");
}
Few questions: Is this is a good way to remove dependencies? I personally don't like to change a method from private to internal but have no option (other than to use Reflection perhaps). Also, the attribute InternalsVisibleTo("MyTests") residing in the production code is not good. Can someone point me to a better solution please? Thanks.
It rather depends on the methods you are changing the scope of. A unit is the smallest testable component of a piece of software - it rarely means one test per method.
I find that comprehensively testing my public methods is enough to establish correct behaviour. You might find that your tests start to constrain your code development if you wrap the private methods with tests.
If your program is more procedural you might find that you need to test at the granular level you describe, in which case using friend assemblies is a fine solution. However, I'd suggest that you would rarely need to test methods that aren't public.
Too much work for too little value. All that test tells me (if it passes) is that calling MyMethod calls another private method. The unit test should be testing the behavior provided by MyMethod() - what should happen/change after a call to MyMethod?.
The title of the question is a bit misleading too - there is no dependency-related issue that I can see.
You do not need InternalsVisibleTo for the most part.. simply test the private method through the public method that exercises it e.g. Write unit tests for MyMethod(). Also if you practice test-first programming, you'd already have tests that cover every line of code in the private method.
Hmm. I have some issues with that code, but we'll do one at a time.
Why would you want to test if MyMethod calls CalculateSomething? It's an implementation detail that is probably likely to change (what if it calls CalculateSomething2 tomorrow but apart from that still does what it's supposed to do?). If you want to test the code structure of MyMethod, do a code review, not a unit test.
You say that MyMethod is complex and you want to test the code flow inside. If there are multiple paths inside, you still have to write a unit test for each path, so why can't you check the result of calling MyMethod instead of checking the inside of it?
Another thought would be to try and refactor MyMethod into methods that lend themselves to easier testing (that's almost automatic if you do test-driven-development, a practice I recommend if you want to do serious unit testing. The "test later" approach almost always leads to code that is much more difficult to test).
If you still want to check the inner workings of MyMethod, maybe you can refactor the private methods you need to check this into another class (say "Calculations" in your example).
Then you can use a mock framework (like RhinoMocks for example), to mock that class. The framework lets you define what functions you expect to be called in what order and what they should return.
Usually you use mocks to lessen the environment requirements for unit tests, but you can use them in this way also.
Can you maybe refactor it to be like this:
public class MyClass
{
private Calculator calculator;
public myMethod()
{
int x = calculateSomething();
}
public void SetCalculator( Calculator c ){
calculator = c;
}
private int calculateSomething()
{
return calculator.CalculateSomething();
}
}
And then have calculator as a separate class and set an instance on MyClass
public Class Calculator {
public virtual int CalculateSomething()
{
// Do something and return an int
return 100;
}
}
You could make Calculator implement an interface and then have a different Calculator implementation or a mock that you use in your tests.
If this is a piece of legacy code that you are too scared to touch, i would advise you to create a unit test which would construct MyClass. Tentatively create a public property in MyClass to expose the value of x.
In the unit test just created assert that value of x is 100 after MyClass is instantiated. Once you have that in place, refactor like #alb suggests. Run the test again, make sure x is still 100 and test the calculator class separately and eventually remove the tentative public property for x in MyClass. hope that helps.

Categories

Resources