Search code examples
c#unit-testingmoqmstest

Trying to moq a class but am unable to access non interfaced methods


Say if I have an Interface

public interface IVehicle<T>
{
    string Drive();
    string Stop();
}

And two classes Car() and Aeroplane()

Each has a class which uses the interface to perform actions

public class CarActions : IVehicle<Car>
{
    public string Drive()
    {
        return "Go";
    }

    public string Stop()
    {
        return "Stop";
    }
}

and

public class AeroplaneActions : IVehicle<Aeroplane>
{
    public string Drive()
    {
        return "Go";
    }

    public string Stop()
    {
        return "Stop";
    }

    public virtual string Fly()
    {
        return "Fly";
    }     
}

When i mock the Aeroplane class, it wont find the fly() method because its not part of the interface

  Mock<AeroplaneActions> mockedDirectly = new Mock<AeroplaneActions>();

        mockedDirectly.Setup(method => method.Drive()).Returns("Drive");
        mockedDirectly.Setup(method => method.Stop()).Returns("Stop");
        mockedDirectly.Setup(method => method.Fly()).Returns("Fly");

I have tried mocking the Actions class directly which does work, however i will need to change my methods to virtual in this case which i would like to avoid.

        Mock<AeroplaneActions> mockedDirectly = new Mock<AeroplaneActions>();

        mockedDirectly.Setup(method => method.Drive()).Returns("Drive");
        mockedDirectly.Setup(method => method.Stop()).Returns("Stop");
        mockedDirectly.Setup(method => method.Fly()).Returns("Fly");

I am wondering if there is any other alternatives to this aside from using virtual methods?


Solution

  • Maybe you could create another interface for the AeroplaneActions, which will inherit from the IVehicle<T> and will have the Fly method e.g. like this:

    public interface IAeroplane<T> : IVehicle<T> 
    { 
        string Fly(); 
    }. 
    

    Then class AeroplaneActions will implement this interface:

    AeroplaneActions : IAeroplane<Aeroplane>
    

    And then it should be possible to mock this interface:

    var mock = new Mock<IAeroplane<Aeroplane>>().