how can protected members of base class be accessed during unit test? - c#

I am creating a unit test in mstest with rhino mocks. I have a class A that inherits class B. I am testing class A and create an instance of it for my test. The class it inherits, "B", has some protected methods and protected properties that I would like to access for the benefit of my tests. For example, validate that a protected property on my base class has the expected value.
Any ideas how I might access these protected properties of class B during my test?

This is wrong approach from unit testing perspectives. You should test only public interface and ensure that it behaves as expected, you should not care details of implementation like private/protected. So there are either:
methods/properties you are going to test really should be public OR
your test case/particular test implementation is wrong
EDIT:
Sometimes when writing unit tests for legacy code which you not able to change you could be forced to access protected members, in this case solution could be creating a wrapper which exposes internal/public property/method to access protected one.
Also what interesting, you marked question by TDD tag, try out imagine how you would be able accessing details of implementation in unit tests when you do not have an implementation yet? This is how TDD works - you have an interfaces and start writing unit tests before an implementation done.

Besides that the other answers point into the right direction, if you really need to test like you described, do this:
Create a class TestA that inherits from A. Use this to make the protected properties of B public for the test. If you have
class B {
protected string Name {get; set;}
}
class A: B {
public void DoSomething(string msg) {
Name = msg.Trim();
}
}
class TestA: A {
public string GetName() {
return Name;
}
}
In your test, now use TestA. I don't know MsTest syntax, but roughly it is this:
[Test]
public void TestThatNameWasSet() {
TestA systemUnderTest = new TestA();
systemUnderTest.DoSomething(" new name ");
Assert.That(systemUnderTest.GetName(), Is.EqualTo("new name");
}

Your protected properties should affect some aspect of the public behaviour of your class.
Test this public behaviour.
As far as your tests are concerned the internal workings of the class should be a black box. This will give you the freedom to refactor without having to mess with your tests. The only important thing is what public stuff they expose and this is what should be tested.

Related

C# unit testing using mocks without interfaces

In order to properly unit test some of my classes I need to mock the class objects being used by the main class being tested. This is a simple process if all the objects being used implements the interface and I only need to use the methods form that interface. However, and here is the problem:
Interfaces are a contract on what other developers should expect in that class. Therefore all interface methods, properties etc. are public. Any good code should also have good encapsulation. Therefore I don't want to make all methods in my class public and hence don't declare it in the interface. And as a result I can not mock and setup these internal method that is used in my main class.
Other options I looked into was using an abstract class that can have different access modifiers and I can have the correct methods in it be internal or private etc. But since I want the class being mocked to be available is a public property of interface type for other developers to use, I need it be an interface, but now its not compatible anymore since my main class cant call the internal method anymore as its defined as an interface. Catch 22. (In case you were wondering, using virtual for methods will have the same problem as using an abstract class).
I have searched for similar questions regarding C# mocking and did not find the same problem I have. And please don't be philosophical on "C# isn't good language for testing" or such stuff. That's not an answer.
Any ideas?
I added this code example to make it easier to see the problem described above.
[assembly: InternalsVisibleTo("MyService.Tests")]
public interface IMyService
{
MethodABC()
...
}
public class MyService : IMyService
{
public void MethodABC()
{
...
}
internal void Initialize()
{
...
}
...
}
public sealed partial class MyMain
{
public IMyService Service { get; private set; }
private MyService _service;
...
private void SomeMethod()
{
// This method is in interface and can be used outside the project when this assembly is referenced
_service.MethodABC()
...
// This method is and internal method inside the class not to be seen or used outside the project.
// 1) When running this method through unit test that mocked the IMyService will fail here since initialize don't exist which is correct.
// 2) Mocking the MyService will require "virtual" to be added to all methods used and don't provide a interface/template for a developers if
// they want to swap the service out.
// 3) Changing the interface to abstract class and mocking that allows for making this an internal method and also set it up in mock to do
// something for unit test and provides contract other developers can implement and pass in to use a different service, but requires
// "override" for all methods to be used from "outside" this assembly. This is best solution but require changes to code for sole purpose
// of testing which is an anti-pattern.
_service.Initialize()
...
}
}
// Unit test method in test project
[TestClass]
public class MyMainTests
{
private Mock<IMyService> _myServiceMock = new Mock<IMyService>();
[TestMethod]
public void MyMain_Test_SomeMethod()
{
...
SomeMethod()
...
}
}
Interface testing doesn't make sense. Interface doesn't say anything about "what it should do". When I need test something with interface, I make MockClass in my NUnit testing class. This class works only for few tests, and it is internal. If you have same namespaces for your tested class and your tests, there should be internal enough. So it is not public. But still you cannot test any private methods.
Sometimes it is annoying, but I cannot have nice code in my tests. But it is not strange.
I get the point of testing only public methods and properties but sometimes this limitation just makes no sense as well as using interfaces just to support unit tests.
My workaround is to inherit the class I am testing, add public access methods and then call protected base class members from it.
One option to consider is to specify the internal actions on an internal interface that you can then use to mock those actions. Given your example, you could add:
internal interface IInitialize
{
void Initialize();
}
And then implement this in your class alongside your public interface:
public class MyService : IMyService, IInitialize
And then your consuming class can use the interface as needed:
public sealed partial class MyMain
{
public MyMain(IMyService myService)
{
Service = myService;
}
public IMyService Service { get; }
public void SomeMethod()
{
(Service as IInitialize)?.Initialize();
Service.MethodABC();
}
}
Now in the unit test you can utilize the As<TInterface>() method in Moq to handle the multiple interfaces (read the docs):
[Fact]
public void Test1()
{
Mock<IMyService> myServiceMock = new Mock<IMyService>();
Mock<IInitialize> myServiceInitializeMock = myServiceMock.As<IInitialize>();
//myServiceMock.Setup(s => s.MethodABC()).Whatever
//myServiceInitializeMock.Setup(s => s.Initialize()).Whatever
MyMain myMain = new MyMain(myServiceMock.Object);
myMain.SomeMethod();
myServiceMock.Verify(s => s.MethodABC(), Times.Once);
myServiceInitializeMock.Verify(s => s.Initialize(), Times.Once);
}
Note the following remark on As<TInterface>():
This method can only be called before the first use of the mock
Moq.Mock`1.Object property, at which point the runtime type has
already been generated and no more interfaces can be added to it.
Also note that the use of As<TInterface>() also requires the following attribute to allow the mock proxy access to implement the internal interface:
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")]
Unfortunately there don't seem to be a clean way of doing this. In order to create a mock using Moq, it needs to be either an interface, abstract class or virtual methods.
Interfaces cant have encapsulation lower than public. Using a internal interface will still force you to create "Public" methods.
Virtual methods allow access modifiers but do not provide an injectable object with a contract to be used by Moq other developers using the main class.
The ideal solution would not require code changes just for the purpose of making it unit testable. This unfortunately don't seem to be possible.
Which brings me to an abstract class that can provide a template (semi interface) that can be handled like an interface but will require "override" for all contract methods but at least will allow correct access modifiers for methods.
This still goes against clean code as I will need to add code to all my methods for the sole purpose of making it unit testable.
This is something Microsoft can look into for new .Net C# features. I will check if they have a feature request for this already.

split test definition and test implementation with nunit, xunit or visual studio test

I'd like to split the definition of test an its implementation like following:
[TestFixture]
public abstract class ContainerTests
{
[Test]
public abstract void BuildContainer();
}
public class UnityTest : ContainerTests
{
public override BuildContainer()
{
// Implementation
}
}
I'd like to have an abstract definition of scenarios and implement it in differnt kind so I can compare them. The TestRunner have to catch all tests from the inherited class even there are definied in the baseclass. Is there any way to do this?
Best regards,
zimmy
with xunit you can happily do :-
public abstract class ContainerTests
{
[Fact]
public abstract void BuildContainer();
}
public class UnityContainer : ContainerTests
{
public override void BuildContainer()
{
Assert.Equal(1,2);
}
}
If it were possible to write the code you give in NUnit, it would mean that every developer of a derived class would have to have a test with the name BuildContainer. That test could test anything at all, or even just be empty. So if your intention is to force devs to implement a test that tests something particular, then this won't do the job.
What you can do, however, is implement the test in the base class using calls to specific abstract methods that the derived class would have to implement. In general, you would want those methods to do something you can assert on in the base class rather having them perform the required asserts yourself.
In general, the lack of ability to override test methods in NUnit is due to a view by the authors that it isn't such a good idea in most cases. I'd be interested to hear of a case that's a counter-example though.

Should I test the methods that are called from the method Im testing in the same test?

Lets say I have the following setup
public interface IClass1
{
int Result(int val);
}
public interface IClass2
{
int Validate(int val);
}
and then we have one class implementing one of these interfaces and taking the other as a parameter in the constructor.
public class Class1 : IClass1
{
private Class2 class2;
public Class1(IClass2 class2)
{
this.class2 = class2;
}
public int Result(int val)
{
return class2.Validate(val);
}
}
If I then create a unit test for the Result method of Class1, should I also test the Validate method of Class2 in the same unit test by injecting an instance of Class2 or should this be a separate test? Am I doing integration testing if I also test the Validate method in the same test this way?
Right now I create a stub of Class2 which returns preset value for Class2.Validate and then checks that the Validate method has been called when Unit Testing Class1.Return.
Am I doing this correct?
Short answer: No.
You should test one thing at a time.
From the perspective of Class1, class2 should just work according to IClass2, and Class1 should not have to "think about it".
Imagine that you replace the implementation of IClass2 at some point in the future - do you then want to have to update the unit tests relating to class1, just because class2 is changed? Probably not.
It's better to keep responsibilities apart, and that is a part of the reason to use Interfaces: From the perspective of Class1, You don't really know what Class2 does, or how it works - only that it is supposed to implement IClass2, and that is enough.
PS: Using testing tools like e.g. FakeItEasy, you could send a fake implementasion of IClass2, and then verify that a call to that is in fact made when the Result() method in Class1 is called.
In other words, Class1 just assumes that the implementation of IClass2 it has been given is trustworthy - all we need to do is make sure that we are in fact making use of it.
Look at the principle of isolation: http://agileinaflash.blogspot.co.uk/2012/04/is-your-unit-test-isolated.html and dirty hybrid tests http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/
and research some isolation frameworks. I've had good success with Moq.
A fully isolated unit test will run only one production method. If you have two instances of classes working together, it's an integration test.
In your case:
public class Class1 : IClass1
{
private Class2 class2;
public Class1(IClass2 class2)
{
this.class2 = class2;
}
public int Result(int val)
{
return class2.Validate(val);
}
}
Using the arrange act assert pattern one of your unit tests for Class1 would be:
[TestMethod]
public void Result_WithValidInput_CallsValidate
{
//used the MethodUnderTest_Condition_ExpectedResult naming convention
//Arrange
IClass2 mockClass2;
//TODO initialise mockClass2 with an a fake object using isolation framework, to return the relevant result to stop the code from falling over during test execution.
Class1 class1UnderTest = new Class1(mockClass2);
//Act
class1UnderTest.Result(1);
//Assert
//TODO use methods from isolation framework to assert that mockClass2.Validate() was called with the correct argument
}
The behaviour of Class1 unit tests proves at it calls into the relevant IClass2 method properly, then the unit tests of Class2 will prove it works properly.
This tests how Class1 interacts with its Members, but this isn't an integration test, since it is against IClass2 and not the production code of Class2. The only production code being called is in Class1 and it is fully isolated from the rest of the code as a unit.
Although, strictly, you don't need to test this since Class2 is private, it's just an implementation detail of Class1.Result(), you don't need to test how Result() does something, just that it does it.
You could also consider making IClass2 a parameter to Result rather than the Class1 ctor, that way it's not being passed in if it's not needed in all methods. This can give you performance benefits if you are using DI to instantiate all of the dependent objects.
No.
Standard practice in cases like this is to pass a 'mock' (of type IClass2 in your case) into your constructor to test Class1.Result. You design the mock to return a specific value, and test that Result does return that value.

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.

NUnit - How to test all classes that implement a particular interface

If I have interface IFoo, and have several classes that implement it, what is the best/most elegant/cleverest way to test all those classes against the interface?
I'd like to reduce test code duplication, but still 'stay true' to the principles of Unit testing.
What would you consider best practice? I'm using NUnit, but I suppose examples from any Unit testing framework would be valid
If you have classes implement any one interface then they all need to implement the methods in that interface. In order to test these classes you need to create a unit test class for each of the classes.
Lets go with a smarter route instead; if your goal is to avoid code and test code duplication you might want to create an abstract class instead that handles the recurring code.
E.g. you have the following interface:
public interface IFoo {
public void CommonCode();
public void SpecificCode();
}
You might want to create an abstract class:
public abstract class AbstractFoo : IFoo {
public void CommonCode() {
SpecificCode();
}
public abstract void SpecificCode();
}
Testing that is easy; implement the abstract class in the test class either as an inner class:
[TestFixture]
public void TestClass {
private class TestFoo : AbstractFoo {
boolean hasCalledSpecificCode = false;
public void SpecificCode() {
hasCalledSpecificCode = true;
}
}
[Test]
public void testCommonCallsSpecificCode() {
TestFoo fooFighter = new TestFoo();
fooFighter.CommonCode();
Assert.That(fooFighter.hasCalledSpecificCode, Is.True());
}
}
...or let the test class extend the abstract class itself if that fits your fancy.
[TestFixture]
public void TestClass : AbstractFoo {
boolean hasCalledSpecificCode;
public void specificCode() {
hasCalledSpecificCode = true;
}
[Test]
public void testCommonCallsSpecificCode() {
AbstractFoo fooFighter = this;
hasCalledSpecificCode = false;
fooFighter.CommonCode();
Assert.That(fooFighter.hasCalledSpecificCode, Is.True());
}
}
Having an abstract class take care of common code that an interface implies gives a much cleaner code design.
I hope this makes sense to you.
As a side note, this is a common design pattern called the Template Method pattern. In the above example, the template method is the CommonCode method and SpecificCode is called a stub or a hook. The idea is that anyone can extend behavior without the need to know the behind the scenes stuff.
A lot of frameworks rely on this behavioral pattern, e.g. ASP.NET where you have to implement the hooks in a page or a user controls such as the generated Page_Load method which is called by the Load event, the template method calls the hooks behind the scenes. There are a lot more examples of this. Basically anything that you have to implement that is using the words "load", "init", or "render" is called by a template method.
I disagree with Jon Limjap when he says,
It is not a contract on either a.) how the method should be implemented and b.) what that method should be doing exactly (it only guarantees the return type), the two reasons that I glean would be your motive in wanting this kind of test.
There could be many parts of the contract not specified in the return type. A language-agnostic example:
public interface List {
// adds o and returns the list
public List add(Object o);
// removed the first occurrence of o and returns the list
public List remove(Object o);
}
Your unit tests on LinkedList, ArrayList, CircularlyLinkedList, and all the others should test not only that the lists themselves are returned, but also that they have been properly modified.
There was an earlier question on design-by-contract, which can help point you in the right direction on one way of DRYing up these tests.
If you don't want the overhead of contracts, I recommend test rigs, along the lines of what Spoike recommended:
abstract class BaseListTest {
abstract public List newListInstance();
public void testAddToList() {
// do some adding tests
}
public void testRemoveFromList() {
// do some removing tests
}
}
class ArrayListTest < BaseListTest {
List newListInstance() { new ArrayList(); }
public void arrayListSpecificTest1() {
// test something about ArrayLists beyond the List requirements
}
}
I don't think this is best practice.
The simple truth is that an interface is nothing more than a contract that a method is implemented. It is not a contract on either a.) how the method should be implemented and b.) what that method should be doing exactly (it only guarantees the return type), the two reasons that I glean would be your motive in wanting this kind of test.
If you really want to be in control of your method implementation, you have the option of:
Implementing it as a method in an abstract class, and inherit from that. You will still need to inherit it into a concrete class, but you are sure that unless it is explicitly overriden that method will do that correct thing.
In .NET 3.5/C# 3.0, implementing the method as an extension method referencing to the Interface
Example:
public static ReturnType MethodName (this IMyinterface myImplementation, SomeObject someParameter)
{
//method body goes here
}
Any implementation properly referencing to that extension method will emit precisely that extension method so you only need to test it once.
How about a hierarchy of [TestFixture]s classes? Put the common test code in the base test class and inherit it into child test classes..
When testing an interface or base class contract, I prefer to let the test framework automatically take care of finding all of the implementers. This lets you concentrate on the interface under test and be reasonably sure that all implementations will be tested, without having to do a lot of manual implementation.
For xUnit.net, I created a Type Resolver library to search for all implementations of a particular type (the xUnit.net extensions are just a thin wrapper over the Type Resolver functionality, so it can be adapted for use in other frameworks).
In MbUnit, you can use a CombinatorialTest with UsingImplementations attributes on the parameters.
For other frameworks, the base class pattern Spoike mentioned can be useful.
Beyond testing the basics of the interface, you should also test that each individual implementation follows its particular requirements.
I don't use NUnit but I have tested C++ interfaces. I would first test a TestFoo class which is a basic implementation of it to make sure the generic stuff works. Then you just need to test the stuff that is unique to each interface.

Categories

Resources