Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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) {
    .
    .
    .
like image 894
Greg Avatar asked May 12 '10 11:05

Greg


People also ask

What are the two approaches to unit testing?

Unit tests can be performed manually or automated. Those employing a manual method may have an instinctual document made detailing each step in the process; however, automated testing is the more common method to unit tests. Automated approaches commonly use a testing framework to develop test cases.

How many types of methods we can test by using unit testing?

There are 2 types of Unit Testing: Manual, and Automated.

What are generic methods generic methods are the methods defined in a generic class?

Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.


4 Answers

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.

like image 130
ema Avatar answered Oct 04 '22 01:10

ema


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...)
like image 45
Julien Roncaglia Avatar answered Oct 04 '22 02:10

Julien Roncaglia


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

like image 26
Christoph Avatar answered Oct 04 '22 02:10

Christoph


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
like image 28
Mahol25 Avatar answered Oct 04 '22 00:10

Mahol25