3

I have a project that supports multiple deployments mode: InMem, OnPremise, Cloud. Also each projects have small services like TimeDistance which can be conected either to WCF, either to an API.

In the unitTestMockup i can say which one i want to use:

Service.TimeDistance = new WCFTimeDistance() / new APITimeDistance().

Until now i had only WCFTimeDistance but now we are in transition mode to move to APITimeDistance but in the meantime i want when i run the tests to run twice, once with WCF once with API.

What's a good approach to do this?

I use C# 4.5
Microsoft.VisualStudio.QualityTools.UnitTestFramework as framework for unitTests

A simple example of desired workflow would be this:

1)Mockup: Service.TimeDistance = new WCFTimeDistance();
2)UnitTest: CheckDistanceBetweenTwoLocationsTest()
{
Service.TimeDistance.CalculateDistance(Location1, Location2) // WCFTimeDistance
}
3)Mockup: Service.TimeDistance = new APITimeDistance();
UnitTest: CheckDistanceBetweenTwoLocationsTest()
{
4)Service.TimeDistance.CalculateDistance(Location1, Location2) //    APITimeDistance
}
sashoalm
  • 75,001
  • 122
  • 434
  • 781
  • 1
    Sorry - What language, what unit testing framework? Also, can you provide a [mcve]? Still, great question! – Mafii Oct 03 '16 at 09:41
  • @AndreiDutu Create two unit tests. Also look into using abstractions instead of static classes. It would make mocking and testing easier – Nkosi Oct 03 '16 at 10:36

1 Answers1

3

Create two unit tests. Also look into using abstractions instead of static classes. It would make mocking and testing easier.

This is for your current setup

[TestClass]
public class TimeDistanceTests {
    //change these to the needed types
    object Location1;
    object Location2;
    double expected;

    [TestInitialize]
    public void Init() {
        //...setup the two locations and expectations
        Location1 = //...
        Location2 = //...
        expected = //...the distance.
    }

    [TestMethod]
    public void Check_Distance_Between_Two_Locations_Using_WCF() {
        //Arrange
        var sut = new WCFTimeDistance();
        //Act
        var actual = sut.CalculateDistance(Location1, Location2);
        //Assert
        //...some assertion proving that test passes or failed
        Assert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void Check_Distance_Between_Two_Locations_Using_API() {
        //Arrange
        var sut = new APITimeDistance();
        //Act
        var actual = sut.CalculateDistance(Location1, Location2);
        //Assert
        //...some assertion proving that test passes or failed
        Assert.AreEqual(expected, actual);
    }
}

Ideally you would want to abstract the service. Assuming something like

public interface ITimeDistance {
    double CalculateDistance(Location location1, Location location2);
}

Your Service would use the abstraction instead of a concretion.

public class Service {
    ITimeDistance timeDistance
    public Service(ITimeDistance timeDistance) {
        this.timeDistance = timeDistance;
    }

    public ITimeDistance TimeDistance { get { return timeDistance; } }
}

So now in your unit tests you can swap the different implementations of your time distance service.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • This is exactly how the service is abstracted. I avoid doing duplicate tests because i already have ~110 UnitTests and would be too much duplicate code. That's how i am doing right now i made a new enum: WCF, API and i run first the unit tests for WCF then for the API. I thought there is a way that i could make all of this automatically – Andrei Dutu Oct 03 '16 at 12:18
  • 1
    @AndreiDutu then look into unit-testing frameworks like NUnit or xUnit, they provide such functionality, e.g. see here: http://nunit.org/?p=testCase&r=2.5 – Mafii Oct 04 '16 at 07:00