I have a class with a construct like this:
private static Dictionary<Contract, IPriceHistoryManager> _historyManagers = new Dictionary<Contract, IPriceHistoryManager>();
and lets say 2 methods like:
public void AddSth()
{
_historManagers.Add(new Contract(), new PriceHistoryManager());
}
public int CountDic()
{
return _historyManagers.Count();
}
Problem:
When running unittests there is no way to "reset" the Dictionary and when i create multiple unittests with seperate instances of the class, then "CountDic" gives unpredictable results and i can't test the listentries.
Question:
Is this generally considered a "bad" approach and if yes: how to do it better/more unittestable?
And if not: How to unittest this best?
Thx.
Don't be afraid to expose public operations for testing purposes. Paraphrased from "The Art of Unit Testing" by Roy Osherove: When Toyota builds a car, there are testing points available. When Intel builds a chip, there are testing points available. There are interfaces to the car or chip that exist only for testing. Why don't we do the same for software? Would a ResetHistory() method completely destroy your API?
If that answer is yes, then create the method, but make the method internal. You can then use the assembly InternalsVisibleTo to expose the guts to your unit test library. You have a method available to you created 100% for testing, but there's no change to your public API.
In your example, CountDic isn't unpredictable: it should return one more than before the call to AddSth().
So:
[Test]
public void Test()
{
var item = new ClassUnderTest();
int initialCount = item.CountDic();
item.AddSth();
int finalCount = item.CountDic();
Assert.That(finalCount == initialCount + 1);
}
In general, though, testing classes that maintain state can be tricky. Sometimes it's necessary to break out the part of the class that maintains state (in your case, the dictionary) and move it to another class. Then, you can mock that "storage" class and pass it in through a constructor.
Related
I have a class called Game. I am wondering what is best practice in this situation to pass the enums in the Game class to the Test class as parameters in a method
Game class has the following:
public enum Result
{
Zero,
One,
etc...
}
public int ResultCount(Result result)
{
switch(result)
{
case Result.Zero
return 0;
case Result.One
retun 1;
etc...
}
}
public void CurrentResult(Result hometeam, Result awayteam)
{
setHomeTeamGoals(hometeam);
setAwayTeamGoals(awayteam);
}
I then have a unit test class where I want to set the result in the setup
[TestFixture]
public class Result_is_1_1
{
private Game _game;
[SetUp]
public void SetUp()
{
_game = new Game();
_game.CurrentResult(Result.One, Result.One);
}
It works when I use the following
using static unitTest.Game;
But I am unsure if this is bad practice/ quick fix etc.
What is the recommended way to do this?
It's difficult to answer your question because you haven't provided complete/working code. But I'm guessing that you defined Result as a nested enum inside the Game class, and that is causing some confusion.
So I assume your Game class looks like this:
public class Game
{
public enum Result
{
Zero,
One,
}
// Other methods...
}
Assuming that's the case, the full name of your enum is Game.Result, because Result is defined within Game.
So when you want to reference the Result enum from your unit test (or from any other class, for that matter), you have two options.
Option 1, reference Game.Result (no using static required):
_game.CurrentResult(Game.Result.One, Game.Result.One);
Option 2, use a using static statement like you've done:
using static unitTest.Game;
// ...
_game.CurrentResult(Result.One, Result.One);
(Bonus third option, you could define the Result enum outside the Game class. Then you don't need to worry about option 1 or 2.)
Assuming I've understood your question correctly, then it's not a bad testing practice. In fact, it doesn't have anything to do with testing at all. It's just a language feature. Personally, I prefer using the full name Game.Result, rather than using the using static statement.
Yes, using static for your class under test is usually a smell indicating bad test design. If you want to have your tests be independent, as is the usual practice for unit testing, create a new Game for each test by instantiating it in your SetUp method - just as you are now doing.
If you want to perform multiple steps in sequence on the same game, the usual approach is to do those steps within the test itself.
If you want each of your test methods to actually be a step that is performed in a certain order, you are getting away from what's generally considered to be unit testing and doing a different type of test. You are also getting away from what NUnit is best at.
However, if you really want to, you can create your Game in a [OneTimeSetUp] method and order all your tests with the OrderAttribute in order to run them in sequence. This makes your tests somewhat fragile because each one depends on all the tests that ran before it.
Given that I have a class in one assembly called GBase with a constructor that takes 2 parameters and a subclass of GBase (call it GDerived) that takes the same parameters, how do I separate these so that I can unit test the subclass?
In OtherAssembly:
public class GBase
{
public GBase(ParamType1 param1, ParamType2 param2)
{
...
}
protected ParamType1 SomeProperty { get; set; }
// other stuff
}
In ThisAssembly:
public class GDerived : GBase
{
public GDerived(ParamType1 param1, ParamType2 param2)
:base(param1, param2)
{
// new code
SomeProperty = newCalculatedValue;
// other stuff
}
// other stuff
}
The original GBase class is legacy code, as is the general structure of the program -- changing the structure is out of the question due to the codebase size (10k lines plus) - none of which has ever had a unit test written for it until very recently.
So now I want to write a test (using NUnit) for the subclass constructor to verify the correct properties are populated with the correct values. Note the test classes are in the same project as the tested classes.
[TestFixture]
public class GDerivedTests
{
[Test]
public void GDerivedConstructor_ValidParams_PropertiesSetCorrectly()
{
var newGDerived = new GDerived(parameter1, parameter2);
Assert.That(SomeProperty == parameter1;
}
}
This is a very crude rep of what we have to deal with, and there are cases other than setting a property in the base class we need to test. I just don't even know for sure where to start. I have Michael Feathers' book Working Effectively with Legacy Code but it doesn't seem to cover this pervasive "design pattern", used extensively throughout the code we are dealing with. Is it because it's so simple any blinking idjyot should know how to deal with it, or is it because it's a rare case? Somehow I don't think it's either, but I could be wrong...
One possible method I thought of is to extract an interface for the base class and mock the base class constructor - but I'm not sure of the details on how to do that. Note we are all relative newbies at unit testing on the team, no experience to draw on. Not coding newbies, just unit test newbies.
TIA,
Dave
To start with: keep it simple! In your example, the only thing you can test is SomeProperty. Everything else is in the base class which you seem that you don't want to test so a test method GDerivedConstructor_ValidParams_PropertiesSetCorrectly() makes no sense. Long-term, it could be wise having tests for it though.
Tests typically contain three elements known as AAA: Arrange, Act and Assert. So write your test like this:
[Test]
public void GDerivedTestOfSomeProperty()
{
// arrange
ParamOfSomeProperty expected = ValueWeAreLookingFor; // this is something that you
// have in newCalculatedValue
// act
GDerived actual = new GDerived(
AnyValueThatMakesThisTestWork1, // maybe null?
AnyValueThatMakesThisTestWork2); // maybe null?
// assert
Assert.AreEqual(expected, actual.SomeProperty);
}
That's it for a start. Go from here. You will soon see that you get lots of redundant code so you possibly want to re-engineer that after a while.
Mocking makes sense for testing the base class or when the base class does some weird stuff with the objects that are injected. In this case, pass in mocks instead of real objects. I personally would use a mocking framework that does all the job for you and you can also use this for testing the base class itself. A famous example is moq.
On a side note: you'll be better off if you move your test classes into its own project. Testing code should not be released for various reasons plus building, testing and deploying may get easier if they are separated.
I'm a little confused about how to perform these test. I know about the existence of PrivateObject to test private class and PrivateType to test private static class, but how can I test a private static method of a PUBLIC static class?
public static class Clients {
// CUT
private static List<string> GenerateAddresses(string AppPath) {
// CUT
}
}
In my unit test class I tried
PrivateType testClients = new PrivateType(Clients);
but I get the error
'Clients' is a type, which is not valid in the given context
The error is a bit confusing and google bring me to completly different problems. Am I using 'Clients' wrong with PrivateType? Or should I test in a different way given that Clients is public?
Or should I test in a different way given that Clients is public?
Yes: Clients is the unit you're testing. If it's not exposing GenerateAddresses publicly, it's not part of its surface API, and in theory is just there to support the internals of the class.
In unit testing, test the observable behaviour of the class - don't worry about how it goes about doing it internally.
var testClients = new PrivateType(typeof(Clients));
PrivateType expects a Type object rather than the symbol name.
But I would rather suggest re-thinking your test strategy. Testing private methods is usually not required. If you find that you are not able to get a decent code coverage from the public methods you may be in need for some refactoring.
I have a folder with assemblies that all contain an implementation of a certain interface (different in each assembly). I have written some unit tests for that interface, and would like to automate the task of running the interface tests on each implementation.
I have a working solution that I don't like:
Write code in the actual test class to load (the assemblies) and instantiate the implementations, store these in a list.
Write each test to loop through the list of implementations, running its assertions on each.
What I want instead is to run all tests on one implementation, then move on to the next to run all tests again, and so on. My thought was to find a way to do something like (programmatically):
Load the assemblies and instantiate the implementations - like before, but not inside the test class.
Create an instance of the test class, injecting the next implementation.
Run the tests.
Move on to the next implementation, repeating the process.
(I realize that I could be shuffling files around in the file system - like put an assembly in one location > run the test which loads one implementation > replace the assembly with the next implementation, and then repeat the process. However, I would like something less crude, if possible.)
I've been looking at the nUnit test-runners (console etc.) for a short cut, but found none so far. Does anyone know if there is a way to achieve what I want using nUnit or any other test suite that can be controlled programmatically? Or maybe there's another way to go about it all, that will satisfy the "what I want" criteria above?
I ended up using the NUnit SuiteAttribute.
This approach involves creating an "umbrella class", like so:
namespace Validator {
public class AllTests {
[Suite]
public static IEnumerable Suite {
get {
var directory = #"[ImplementationAssembliesPath]";
var suite = new ArrayList();
// GetInstances is a method responsible for loading the
// assemblys and instantiating the implementations to be tested.
foreach (var instance in GetInstances(directory)) {
suite.Add(GetResolvedTest(instance));
}
return suite;
}
}
// This part is crucial - this is where I get to inject the
// implementations to the test.
private static Object GetResolvedTest(ICalculator instance) {
return new CalculatorTests {Calculator = instance};
}
[...]
}
Note that the test class has a property for injecting the implementation I want. I choose a property injection because the test-runners usually dislike other than default constructors. However, I had to remove the TestFixtureAttribute from the actual test class (omitted here) to not confuse the Console-Runner on what to run.
Then I created a simple console application to run the NUnit Console-Runner with the /fixture argument:
namespace TestRunner {
using System;
using NUnit.ConsoleRunner;
internal class Program {
private static void Main(String[] args) {
var testDllPath = #"[TestAssemblyPath]/Validator.dll";
var processArgument = #"/process=Separate";
var domainArgument = #"/domain=Multiple";
var runtimeArgument = #"/framework=4.5";
var shadowArgument = #"/noshadow";
var fixtureArgument = String.Format(#"/fixture={0}", "[Namespace].AllTests");
Runner.Main(new[] {
testDllPath,
processArgument,
domainArgument,
runtimeArgument,
shadowArgument,
fixtureArgument
});
Console.ReadLine();
}
}
}
I would still be interested in hearing your opinion on this, and on alternative solutions.
If you want to test a fixed set of assemblies you don't have to do fancy stuff like moving assemblies or instructing test runners.
Like with normal classes you can use inheritance for your unit test classes. I would suggest that you create an abstract base class which does the heavy lifting for testing implementations of this interface. For each implementation of the interface you can create a new class which inherits from the base class.
The base class can look like this:
public class BaseMyInterfaceImplementationTest
{
protected MyInterface ClassUnderTest;
//Add your tests here with the [Test] attribute:
[Test]
public void TestScenario1()
{
//do your test on ClassUnderTest
}
}
And the derived classes like this:
[TestFixture]
public class Implementation1Tests : BaseMyInterfaceImplementationTest
{
[SetUp]
public void BaseTestInitialize()
{
ClassUnderTest = new Implementation1();
}
}
This is my first question so please be kind! :)
What I am trying to do is write some tests for a manager class that during construction adds many new instances of a single item class to a list. When the UpdateAllItems is called in this manager class the intention is to iterate the list and call Increment on each single item.
The manager class is my code, but the single item class is not so I can't modify it.
I use NUnit for a testing framework and am starting to work with Moq. Because the manager class uses the single item class I would think I need to use a Moq so I am testing only the manager, not the single item.
How do I write tests for my UpdateAllItems method? (Technically I should be writing the tests first I know).
Here is a some sample code that gives a general idea of what I am working with...
public class SingleItem_CodeCantBeModified
{
public int CurrentValue { get; private set; }
public SingleItem_CodeCantBeModified(int startValue)
{
CurrentValue = startValue;
}
public void Increment()
{
CurrentValue++;
}
}
public class SingleItemManager
{
List<SingleItem_CodeCantBeModified> items = new List<SingleItem_CodeCantBeModified>();
public SingleItemManager()
{
items.Add(new SingleItem_CodeCantBeModified(100));
items.Add(new SingleItem_CodeCantBeModified(200));
}
public void UpdateAllItems()
{
items.ForEach(item => item.Increment());
}
}
Thanks in advance for all the help!
The simple answer is, you can't. The method that UpdateAllItems calls (Increment()) is non-virtual, so you won't be able to mock it.
Your options, as I see it, are:
Don't test UpdateAllItems at all. Its implementation is trivial, so this is an option to consider (though not ideal).
Create real SingleItem_CodeCantBeModified instances in your test. Purists would say that you no longer have a unit test at this point, but it could still be a useful test.
Add an ISingleItem interface, and an SingleItemAdapter : ISingleItem class that holds onto a reference to a SingleItem_CodeCantBeModified and forwards the calls. Then you can write SingleItemManager to operate on ISingleItems, and you'll be free to pass in mock ISingleItems in your tests. (Depending on how your system is set up, you might even be able to descend from SingleItem_CodeCantBeModified, implement the interface on your descendant, and use those objects instead of writing an adapter.)
That last option gives you the most options, but at the cost of some complexity. Choose the option that's best suited for what you're trying to accomplish.
Your Manager is too dependent on Item (in List<Item>). Can you extract list population into separate class to be able to mock it? e.g.:
public SingleItemManager()
{
items.Add(ItemRepository.Get(100));
items.Add(ItemRepository.Get(200));
}
Testing (some code omitted):
int i = 0;
var itemMock = new Mock<Item>();
itemMock.Setup(i => i.Increment()).Callback(() => i++);
var repositoryMock = new Moc<ItemRepository>();
repositoryMock.Setup(r => r.Get(It.IsAny<int>()).Returns(itemMock.Object);
var manager = new SingleItemManager();
manager.UpdateAllItems();
Assert.AreEqual(i, 1);
As usual, you can add another level of indirection.
Create a wrapper class around SingleItem_CodeCantBeModified
Make this wrapper inherit IItem interface
Make SingleItemManager depend on IItem instead of SingleItem_CodeCantBeModified
OR
If Increment is a virtual method (I understand it isn't in your sample code, but just in case), use partial mocking.
Instead of hard-coding your additional concrete items, have the SingleItem_CodeCantBeModified implement an interface (or embed it in a wrapper which implements the interface) then pass in a (new) factory which will create these items.
In your test you will create a mock of the factory to pass in to your Manager class, then you can monitor what methods are called on that mocked object.
Although this would be more about testing the internals of the system, not the byproducts. What interface is the Manager implementing? If it's not proving itself externally, what results are you testing for?