Greg
Greg

Reputation: 34798

Unit test approach for generic classes/methods

What's the recommended way to cover off unit testing of generic classes/methods?

For example (referring to my example code below). Would it be a case of have 2 or 3 times the tests to cover testing the methods with a few different types of TKey, TNode classes? Or is just one class enough?

public class TopologyBase<TKey, TNode, TRelationship> 
    where TNode : NodeBase<TKey>, new() 
    where TRelationship : RelationshipBase<TKey>, new()

{
    // Properties
    public Dictionary<TKey, NodeBase<TKey>> Nodes { get; private set; }
    public List<RelationshipBase<TKey>> Relationships { get; private set; }

    // Constructors
    protected TopologyBase()
    {
        Nodes = new Dictionary<TKey, NodeBase<TKey>>();
        Relationships = new List<RelationshipBase<TKey>>();
    }

    // Methods
    public TNode CreateNode(TKey key)
    {
        var node = new TNode {Key = key};
        Nodes.Add(node.Key, node);
        return node;
    }

    public void CreateRelationship(NodeBase<TKey> parent, NodeBase<TKey> child) {
    .
    .
    .

Upvotes: 11

Views: 8935

Answers (5)

Dan Bryant
Dan Bryant

Reputation: 27495

A lot depends on your generic constraints. If one or more of type parameters requires an interface or base class constraint, there is now a dependency on the interface contract. Since the logic of your class may partially depend on the behavior of the class implementing the interface, you may need to mock the interface in various ways to exercise all of your logical pathways. For instance, if you have T: IEquatable<T>, you'll need to use a type with meaningful equality behavior, like an int.

Upvotes: 0

Julien Roncaglia
Julien Roncaglia

Reputation: 17837

It could really depends on your code but there are at least two things to think about :

  • Private / Public : If your implementation use or may someday use reflection or the DLR (directly or via the dynamic keyword in C#) for some operations you should test with at least one type that isn't visible from the implementing assembly.
  • ValueType / ReferenceType : The difference between them could need to be tested in some cases for example
    • Calling Object method on value types, like ToString or Equals is always correct, but not with references as they can be null.
    • If you are doing performance testing there could be consequences to passing around value types, especially if they are big (Shouldn't happens but between guidelines and reality sometimes there is a small gap...)

Upvotes: 2

Mahol25
Mahol25

Reputation: 3201

To unit test an open production type, create a test code type that derives from the open type - then test that type.

public class TestingTopologyBase : TopologyBase<KeyType, NodeType, RelationshipType> ...

In the TestingTopologyBase class, provide a base implementation of any abstract methods or anything else that is mandatory.

These Testing[ProductionType] implementations are often excellent places for your unit test code to sense what the generic type under test is actually doing. FOr instance, you can store away information that can later be used by your unit test code to inspect what went on during the test.

Then in your unit test methods, create instances of the TestingTopologyBase class. This way, you test the generic type in isolation from any production types that derive from it.

Example:

[TestClass]
public class TopologyBaseFixture {

    [TestMethod]
    public void SomeTestMethod() {
       var foo = new TestingTopologyBase(...);
       ...test foo here

Upvotes: 1

Christoph
Christoph

Reputation: 4401

You could use a mocking framework to verify expected interaction between the your class and the generic type. I use Rhino Mocks for this.

Upvotes: 1

ema
ema

Reputation: 5773

I usually create a DummyClass for test purpose to pass as a generic argument (in your case you should create 3 class) and the I test the class (TopologyBase) once.

Testing with different generic types doesn't make sense, since the generic type should not break the ToopologyBase class.

Upvotes: 5

Related Questions