I got a unit test (MStest)
There is a test class that has a lot of test methods.
If I run all methods from TestExplorer, each method will invoke the constructor.
Is there any way to save TestClass instance across all of these methods?
well, there are multiple different attributes that indicate when a method should be invoked. When you want a setup to run only once for all tests, you should use the ClassInitialize -attribute, not the constructor:
[TestClass]
class MyTests
{
[ClassInitialize]
public static void SetupTests(TestContext context) { ... }
}
Performing initializations from within the constructor is merely a bad idea, as every test-framework has its own plan on when and how often to invoke those. Instead you should use the attributes which are deterministic in their use.
If you need initialization to happen before every test, you may use the TestInitialize-attribute.
Related
My class has a method like this:
internal virtual Something CreateSomething(){...}
It was done this way so that in testing I can stub CreateSomething() to return a mock object:
var something = ...; //some mock object
var t = MockRepository.GenerateStub<MyObject>();
t.Stub(x => x.CreateSomething()).Return(something);
This worked fine but now CreateSomething() is called in the class constructor, before it was called later on, so by the time I stub the method my object is already created.
Is there a workaround that doesn't involve changing the design, to pass stub methods in at construction time? If not I can consider changing the design to use construction-injection (which I'm sure some of you are itching to suggest anyway!) but I'd rather see if Rhino supports this use-case first.
There is no way to stub the method before it is invoked from its class constructor. This is C# limitation. And this is reasonable.
In general it is a bad practice to call virtual method from the constructor, because likely the result will not be what is expected. See details here: Virtual member call in a constructor.
So, I highly recommend to either make this method non-virtual, or avoid its invocation from the constructor.
Anyway in such situation it won't work as virtual.
Regarding you question about testing the method, which is called from constructor.
I presume, this is a private method. Otherwise it could be tested as a regular public method.
As it is private, then there is no need to test this particular method in isolation. I recommend to follow general approach in testing constructors and testing private methods: Do not test private methods.
Test the public visible effect instead. That could be:
Public property initialization
Mocked dependencies invocation or properties access
Exception thrown
etc.
Please also find more details about this topic by the links below:
Is it important to unit test a constructor?
Unit testing private methods in C#
In xUnit I need to run some code once, before any test is executed, and also some code after all tests are done. Although this thread explains how to do it quite well, I want to do some printing inside the constructor and destructor, like shown in the code below, and that's the tricky part. Since Console.Writeline won't work, I looked for a workaround, which I found in this link.
public class TestsFixture : IDisposable
{
protected readonly ITestOutputHelper _output;
public TestsFixture(ITestOutputHelper output)
{
_output = output;
// Do "global" initialization here; Only called once.
_output.WriteLine("global init");
}
public void Dispose()
{
// Do "global" teardown here; Only called once.
_output.WriteLine("global teardown");
}
}
public class HandlerTests : IClassFixture<TestsFixture>
{
// All my tests are here
}
A brief explanation on what's going on here:
This code uses the IUseFixture interface to ensure that the global
initialization/teardown functionality is only called once. For this
version, you don't extend a base class from your test class but
implement the IUseFixture interface where T refers to your fixture
class
Everything seems fine, but when I run the tests, I get an error (below). Any idea on how to solve this problem?
Test Outcome: Failed
Test Duration: 0:00:00,001
Result Message: Class fixture type 'TestsPlatform.TestsFixture' had one or more unresolved constructor arguments: ITestOutputHelper output
The documentation says that you can add a parameter of type ITestOutputHelper to the constructor of the test class. I don't see anything that says you can add it as a parameter to the constructor of a test fixture class...
It wouldn't make sense for this output to go via ITestOutputHelper because the whole point of that mechanism is to allow the output to be associated with a specific test. Your setup/teardown is global, not per-test.
You'll need to find another way to output those diagnostics.
I have a method call that I am unit testing. Inside that method call it makes a call to a method that is going to throw an error because it is trying to talk to a device that will not be available when the unit test is running. Is there a way to avoid that internal method call from being called?
Environment: C# Visual Studio 2010 unit testing within IDE
If you're unit testing a class with external dependencies then you must isolate the external dependancies using an interface which is injected in.
interface IDevice
{
void Run();
}
interface IDeviceOperator
{
void Operate();
}
class DeviceOperator : IDeviceOperator
{
private readonly IDevice _device;
public DeviceOperator(IDevice device)
{
_device = device;
}
public void Operate()
{
_device.Run();
// test other stuff here
}
}
[TestFixture]
public class DeviceOperatorTests
{
[Test]
public void Test_DeviceOperator_Operate()
{
IDevice device = A.Fake<IDevice>(); // Using FakeItEasy 3rd party mocking framework syntax
DeviceOperator deviceOperator = new DeviceOperator(device);
deviceOperator.Operate();
}
}
When doing unit testing you have to create mocks or stubs for all your external dependencies. A framework that could help you with that is Moq (it is plenty of mock frameworks if you want to explore).
These mock or stubs are just facades providing necessary interactions and data to pass your tests.
We may be able to help you more if you provide more details about that unavailable device.
There's probably a better way, but once or twice I've been in this situation where a method calls another, complicated method, and put an optional parameter at the end of the method you're testing like
public void DoSomething(int number, bool skipMethod= false)
{
if(!skipMethod)
MethodThatWillBreak();
{
So that in the normal course of running, it'll be fine, but in your unit test you can do
DoSomething(2,true);
But really, it suggests that you need to do some refactoring of your code, because your unit test should only be hitting one "unit". If you can test the method without calling the MethodThatWillBreak then what is it doing there in the first place.
Check out Working Effectively with Legacy Code book by Michael Feathers - it have a lot of suggestions on dealing with code that does not have unit test yet.
Possible approaches covered in the book:
extract dependency in interface - ideal approach (see jamespconnor's answer)
use flag to bypass call (see Colm Prunty's answer)
extract that call into virtual method and override in derived class used in unit test
pass delegate (may be less impact than full interface/derivation)
Sample for deriving from the class:
public class WithComplexDependency
{
public void DoSomething()
{
// Extract original code into a virtual protected method
// dependency.MethodThatWillBreak();
CallMethodThatWillBreak();
}
virtual protected void CallMethodThatWillBreak()
{
dependency.MethodThatWillBreak();
}
}
in test code derive from the class and provide own implementation:
public class WithMockComplexDependency : WithComplexDependency
{
// may also need to add constructor to call original one.
override protected void CallMethodThatWillBreak()
{
// do whatever is needed for your test
}
}
...
WithComplexDependency testObject = new WithMockComplexDependency();
testObject.DoSomething(); // now does not call dependency.MethodThatWillBreak()
...
To unit test correctly you should decouple the comunication with the device from the class you want to test! Abstract the partetalking to the device in another class implementing an interface, inject the communication class in the ctor of the object under test, now you can inject a mock implementation from outside and avoid the errore,the mmock implementation can also log call made to it or respond in a predefined way easing test.
Read a out dependency injection and inversion of control
Typically you would extract external dependencies from the class you're testing and will swap them with fake ones in your unit test. You would isolate them and test the part that you're interested in. I recommend that you look into Inversion of Control as well as one of the many Mocking Frameworks (Moq, Rhino Mocks etc.)
You probably don't want to SKIP the external. Instead you want to isolate the external dependencies such as accessing external devices. There are many ways to do this
a. You can use a third part isolation framework such as Moq, or RhinoMock, etc
b. You can use Moles framework (since you are using VS2010) - replace a .NET method with a delegate
http://research.microsoft.com/en-us/projects/moles/
c. Paid isolation frameworks such as TypeMock.
d. Or simply hand written fake implementation which uses in interface and your test uses the Fake implementation.
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]
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!