Testing working of internal functions using nunit tests - c#

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!

Related

Does a [TestMethod] have to be public? What consequences are there if it isn't?

I am using the test facilities provided by Microsoft.VisualStudio.TestPlatform.TestFramework. I have a test method decorated with [TestMethod]. I want to implement this test for various combinations of parameters using [DataRow]. One of the parameters that the method will need is an enum type declared as internal in another assembly; the assembly in which the enum type is defined gives the assembly containing the unit tests access to its internals via InternalsVisibleTo.
Unit test methods are conventionally public within a public class, so far as I can tell. When it comes to this unit test method, either the test method must be inaccessible from outside the unit test assembly (achieved by making it private or internal, or by making the test class that contains it internal) or the enum must be made public. Making the enum public would be inappropriate, so it would appear correct to make the test method internal.
Are there any possible negative consequences to making the unit test method internal?
This question is doubtless a simple one that has a simple answer. I am asking it because I am having no success at all searching the internet for an answer to it. All I can locate are discussions about whether one should test private methods or not.
Note: If you give a comment or answer that fails to answer my question but instead suggests or implies that it's wrong to test internal members of an assembly using InternalsVisibleTo, then I shall reject your answer out of hand.
Note 2: One possible thing to be done in this case is to use a string parameter instead of the enum parameter, use Enum.Parse in the test method, and pass all of the relevant parameters as strings constructed using the nameof operator. I don't like this, but it might be the least bad workaround.
At least for MSTest, the test runner in visual studio won't detect methods that aren't public when run. Here's a quick sample.
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1() => Assert.IsTrue(true);
[TestMethod]
internal void TestMethod2() => Assert.IsTrue(false);
}
Results are that one test was detected, run, and passed. So I would consider that a major negative consequence to not having the test methods public.
[TestMethod]s have to have public access. Here's Microsoft's documentation on the matter.
The consequence is it will not run if private.

Should protected methods be unit-tested? How to avoid repetitive testing?

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.

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]

Unit Testing - best practice

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

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