Mocking a private field - c#

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

Related

Mocking a protected member without reflection

I have a member that returns a string from a resource file, and I want to unit test this, as there's quite a few and they could be changed by mistake. I understand that this is achievable using reflection but I've been asked to do it in a way that doesn't use reflection.
The members look something like this;
protected override string StringOne
{
get
{
return Resources.String;
}
}
I understand that setting up the return for the member can be done as;
mock.Protected()
.Setup<string>("StringOne")
.Returns("Returned string.");
and .verifiable() can be added to the end of this. But I can't find how to verify that a string is being returned. Or am I right in thinking that the by setting this up with .verifiable(), that the .returns("") value is the expected, and calling
mock.Verify();
will verifying that the member has returned the correct string or simply that the member was called at some point during the test?
The problem that you are encountering here is that you are trying to test something that isn't available from outside of the class. Tests should only test the public interface of your class so that the internals of the class can change as long as the public behaviour remains the same.
In this instance, I think that you have two options:
One is to move this code into another class with these properties being public, that way your test can just call the new public properties and check the return and the classes that need to use the value of the property can call your new class. Inheritance is generally not a great way of sharing code anyway (a blog post explaining this concept: http://www.blinkingcaret.com/2016/04/13/composition-superior-inheritance/)
The other is to test where these properties end up being used. For example, if you have some method that passes the value of StringOne into another mocked class, you can check that the correct value is passed through or if it ends up being used in a file path, you should test that the file path ends up being correct etc

Can I set private readonly instance variable?

I'd like to know if somehow it is possible to set private readonly class variable via reflection or something?
Consider the following class:
public class TestSevice
{
private readonly someClassType m_variable;
public TestService()
{
m_variable = //call to some processing function
}
private static int CalculateStuff(int x, int y)
{
//some processing and return
}
}
I'm writing a unit test for private static method CalculateStuff(int x, int y), which I'm able to call via reflection:
PrivateType pt = new PrivateType(typeof(AvatarService));
int actialRes = (int)pt.InvokeStatic("CalculateStuff", parameters);
The problem is that, for my unit test to work, I don't want to set m_variable or set it to null on invoking the static function.
So, is it possible with a constructor is parameterless ctor to not set m_variable or custom set to to something in the unit test?
Edit:
Some details on //call to some processing function
Here, a call is made to start the receiver of message queue.
The class TestService is instantiated on the start of worker role, and hence the queue receiver is started in the ctor. The message queue receiver then calls a wrapper function in TestSevice class, which in turn calls CalculateStuff. And since I just want to test the core business logic, I don't want to start queue receiver(which imposes certain dependencies).
If you are trying to test a class by modifying its behavior you have already missed the point.
If there is a way that class can get into a certain test then that's how you should test it. With read only the only way to do that is through a constructor.
If the property is read only it suggests you only want to instantiate it once for a specific instance of that class and know it can't change. If that's the case the you shouldn't want to change it but possibly instantiate another instance.
If it needs to be changed before each call on calculate and you are in a situation where you think you need the function to be static, then you should probably have it as an extra parameter. This means it can longer be read only. Doing it this way would disconnect it from the state of a given instance but if you are trying/need to change the value it shouldn't be read only.
Apparently the answer is yes. https://stackoverflow.com/a/934942/2540156 But that doesn't really sound like your issue. It sounds like you want an alternate constructor to call during unit testing that will prevent the code from running that sets your variable. For that you'll have to make a change to your constructor.

What are the good practice to test/inject private field in C#

My apologies if this a duplicate. I have been given the task to add some coverage for the method and been told to mock the private List<string> property. My question is: Is there a way to test private fields?
The solution I found is adding new constructor just to inject this private list. I am not sure whether this is the right way, so any help will be highly appreciated.
public class Class1
{
public Class1(List<string> list)//This is just for Unit Testing
{
list1 = list;
}
private readonly InjectRepository _repository;
//
public Class1(InjectRepository repository)//This is the actual constructor
{
_repository = repository;
}
private List<string> list1 = new List<string>();
public void Do_Complex_Logic()
{
//list1 will be set with items in it
//Now list1 is passed to some other instance
}
}
The private logic of a class should be visible in the public expression of its behavior. In other words, the theory goes, there should be no need to test private fields at all.
There is no way to directly test private fields; they are private after all. If you really think that testing a private field is required, then I would suggest making it internal instead, and exposing it to your unit testing assemblies via the [InternalsVisibleTo] attribute.
That being said, there are frameworks that allow such things, such as TypeMock.
Don't test private fields or methods. Test the behaviour of a contract - public or internal methods.
That said, you can try:
Option A
Make private members internal and set InternalsVisibleTo attribute for the assembly under test.
Option B
Write a wrapper class that wraps you private fields/methods into public ones. This approach has a benefit that you don't need to make your private methods internal. The downside is that for every private method you will have a wrapper public method. So the amount of methods may double.
Adding to what womp & oleksii have already said -
The fact that you want/need to test a private method is a sign (smell?) that your design may be incorrect. This is one of the positive side-effects of TDD (and my personal favorite).
An example:
I don't fully know your domain here, but one simple change could be to, instead of Do_Complex_Logic taking no parameters, you could have it take and return a List<string>:
public List<string> Do_Complex_Logic( List<string> input )
I know - it's simple, but try deconstructing your class a bit and build it back with the tests in mind first.
I'm not disagreeing with the other answers; but in this case I think the most appropriate thing to do - given your code; is to change the signature of
'Do_Complex_Logic'
The real problem is that you are dealing with the 'state' of List1. If you pass List1 into Do_Complex_Logic - your problem is mostly solved. Your comment says that 'Do_Complex_Logic' is going to (presumably) do some work on List1 and then pass it into something else, right?
Make Do_Complex_Logic take a List and return a List. Now it's easy to test. Instead of depending on the state of List1 being setup correctly in your class, you can 'inject the dependency'.
How does the private field get prepared in the first place? If it is through interactions with the repository then you could possibly mock that object.
One way to do that is to interact with your repository through an interface (let's call it IInjectRepository rather than a concrete entity and then use something like Moq (or one of the many plethora of mocking frameworks out there) to populate your data via a mock'd repository as you setup your test. After you have called Do_Complex_Logic I assume you have a way of interrogating the entity so that you know it has done what you expected to. This way you can avoid/mitigate adding methods and classes that are for test only.
You could use reflection as mensioned in answer https://stackoverflow.com/a/3376157/1523402 of a related question.
I don't know if private accessors also work for private fields. But they help (at least) for private methods (see http://msdn.microsoft.com/en-us/library/ms184807%28v=vs.80%29.aspx).

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