Skip to main content
added 1396 characters in body
Source Link
Frits
  • 430
  • 1
  • 3
  • 9

An example:

    namespace XUnitSample.ClassLib.Interfaces
    {
        public interface ICalculationEngine
        {
            int Add(int num1, int num2);
            int Minus(int num1, int num2);
        }
    }

    namespace XUnitSample.ClassLib
    {
        public class Cal
        {
            private readonly ICalculationEngine _calculationEngine;

            public Cal(ICalculationEngine calculationEngine)
            {
                _calculationEngine = calculationEngine;
            }

            public int Add(int num1, int num2)
            {
                return _calculationEngine.Add(num1, num2);
            }

            public int Minus(int num1, int num2)
            {
                return _calculationEngine.Minus(num1, num2);
            }
        }
    }
    namespace XUnitSample.Lib
    {
        public class CalTest
        {
            [Fact]
            public void Add_Add2Numbers()
            {
                // Arrange
                var mock = new Mock<ICalculationEngine>();
                mock.Setup(x => x.Add(1, 1)).Returns(2);

                var cal = new Cal(mock.Object);

                // Act
                var result = cal.Add(1,1);

                // Assert
                Assert.Equal(result, 2)
            }
        }
    }

An example:

    namespace XUnitSample.ClassLib.Interfaces
    {
        public interface ICalculationEngine
        {
            int Add(int num1, int num2);
            int Minus(int num1, int num2);
        }
    }

    namespace XUnitSample.ClassLib
    {
        public class Cal
        {
            private readonly ICalculationEngine _calculationEngine;

            public Cal(ICalculationEngine calculationEngine)
            {
                _calculationEngine = calculationEngine;
            }

            public int Add(int num1, int num2)
            {
                return _calculationEngine.Add(num1, num2);
            }

            public int Minus(int num1, int num2)
            {
                return _calculationEngine.Minus(num1, num2);
            }
        }
    }
    namespace XUnitSample.Lib
    {
        public class CalTest
        {
            [Fact]
            public void Add_Add2Numbers()
            {
                // Arrange
                var mock = new Mock<ICalculationEngine>();
                mock.Setup(x => x.Add(1, 1)).Returns(2);

                var cal = new Cal(mock.Object);

                // Act
                var result = cal.Add(1,1);

                // Assert
                Assert.Equal(result, 2)
            }
        }
    }
Source Link
Frits
  • 430
  • 1
  • 3
  • 9

When I write a unit test, I use the 'AAA' pattern: Arrange, Act, Assert. For your second unit test, it would look like this:

    [Theory]
    [InlineData(1,2,3)]
    [InlineData(1, 1, 2)]
    [InlineData(1, 0, 1)]
    public void Add_Add2Numbers_Theory(int num1, int num2, int expected)
    {
        // Arrange
        var cal = new Cal();

        // Act
        var result = cal.Add(num1, num2);

        // Assert
        Assert.Equal(expected, result);
    }

That way, you have a clear separation of the setup, the execution and the checks in the unit test. More on this subject can be found on numerous sites, like this one: Understand AAA in Unit Testing.

In the first and third unit test, you are using 'mocking' wrong. Mocking is used to replace dependencies. In this case, the ICal interface is not a dependency of the Cal class, it is just the interface that the Cal class is implementing. So there is no use in mocking it.

Mocking comes in place when your Cal class depends on some other class or library, for example a "CalculationEngine". Then the constructor of the Cal class looks like this:

    public Cal(ICalculationEngine calculationEngine)
    {
        _calculationEngine = calculationEngine;
    }

In such case, when you test the Cal class, you need to mock the CalculationEngine. And then, you can control the behaviour of this dependency by supplying specific setups for its methods.