XUnit Testing using Autofac.Extras.Moq

380 Views Asked by At

I'm new in unit testing, Below is code for unit testing using xunit

public class FloorManager
{
    public List<FloorInfo> Floors { get; }

    public FloorManager()
    {
        Floors = new List<FloorInfo>();
        SelectedFloor = -1;
    }        

    public FloorInfo FindFloorByName(string name)
    {
        FloorInfo fInfo = Floors.Find(floor => floor.Name == name);
        return fInfo;
    }
}

public class FloorInfo
{
    public String Name { get; set; }
}

I have a test for it:

[Fact]
public void FindFloorByName_ShouldGetName()
{
    using (var mock = AutoMock.GetLoose())
    {
        string floorName = "First Floor";
        var fInfo = new FloorInfo { Name = floorName };
        mock.Mock<FloorManager>()
            .Setup(x => x.FindFloorByName(floorName)).Returns(fInfo);

        var cls = mock.Create<FloorManager>();
        var expected = "First Floor";

        var actual = cls.FindFloorByName(floorName);

        Assert.True(expected == actual.Name);
    }
}

but when i run test it gives me error :-

> `System.NotSupportedException : Unsupported expression: x => x.FindFloorByName(FloorManagerTests.<>c__DisplayClass0_0.floorName)`

Please give me solution how to test above function to pass test case

1

There are 1 best solutions below

0
Nkosi On

There is nothing to mock in the shown code example provided in the original question.

Also the subject under test (SUT) is usually not mocked when unit testing in isolation

Given the following class as an example

public class FloorManager {
    private List<FloorInfo> floors;

    public FloorManager() {
        floors = new List<FloorInfo>();
    }

    public IEnumerable<FloorInfo> Floors => floors;

    public FloorInfo FindFloorByName(string name) {
        FloorInfo fInfo = floors.Find(floor => floor.Name == name);
        return fInfo;
    }

    public  void Add(FloorInfo floor) {
        floors.Add(floor);
    }
}

public class FloorInfo {
    public String Name { get; set; }
}

Some simple tests for the public facing members of the subject class

[TestClass]
public class FloorManagerTests {
    [TestMethod]
    public void Should_Create_Default_FloorManager() {
        //Arrange
        FloorManager subject = null;

        //Act
        subject = new FloorManager();

        //Assert - FluentAssertions
        subject.Should().NotBeNull();
        subject.Floors.Should()
            .NotBeNull()
            .And.HaveCount(0);
    }

    [TestMethod]
    public void Should_Add_Floor() {
        //Arrange
        string floorName = "First Floor";
        var floor = new FloorInfo { Name = floorName };
        var subject = new FloorManager();

        //Act
        subject.Add(floor);

        //Assert - FluentAssertions
        subject.Floors.Should().HaveCount(1);
    }

    [TestMethod]
    public void Should_FindFloorByName() {
        //Arrange
        string expected = "First Floor";
        var floor = new FloorInfo { Name = expected };
        var subject = new FloorManager();
        subject.Add(floor);

        //Act
        FloorInfo actual = subject.FindFloorByName(expected);

        //Assert - FluentAssertions
        actual.Should().NotBeNull();
        actual.Name.Should().Be(expected);
    }
}

And as more complexity is added to the subject class, more tests can be added to verify expected behavior.

If the manager was instead dependent on a service

For example,

public class FloorManager {
    private IFloorCollection floors;

    public FloorManager(IFloorCollection floors) {
        this.floors = floors;
    }

    public IEnumerable<FloorInfo> Floors => floors.All;

    public FloorInfo FindFloorByName(string name) {
        FloorInfo fInfo = floors.Find(floor => floor.Name == name);
        return fInfo;
    }

    public void Add(FloorInfo floor) {
        floors.Add(floor);
    }
}

public interface IFloorCollection {
    IEnumerable<FloorInfo> All { get; }
    void Add(FloorInfo floor);
    FloorInfo Find(Func<FloorInfo, bool> p);

}

public class FloorInfo {
    public String Name { get; set; }
}

Then there would be a need to mock the dependency in order to test the subject in isolation.

[TestMethod]
public void Should_FindFloorByName() {
    using (var mock = AutoMock.GetLoose()) {
        //Arrange
        string expected = "First Floor";
        var floor = new FloorInfo { Name = expected };
        FloorManager subject = mock.Create<FloorManager>();
        mock.Mock<IFloorCollection>()
            .Setup(_ => _.Find(It.Is<Func<FloorInfo, bool>>(f => f(floor))))
            .Returns(floor);

        //Act
        FloorInfo actual = subject.FindFloorByName(expected);

        //Assert - FluentAssertions
        actual.Should().NotBeNull();
        actual.Name.Should().Be(expected);
    }
}