C#如何在没有实现的情况下对接口方法进行单元测试

Axe*_*ton 6 c# unit-testing dependency-injection moq

我是单元测试和 stackoverflow 的新手。

我必须RefreshAmount在以下界面中进行测试:

public interface IAccountService
{
    double GetAccountAmount(int accountId);
}
Run Code Online (Sandbox Code Playgroud)

这是一个依赖于这个接口的类:

public class AccountObj
{
    private readonly int _Id;
    private readonly IService _service;
    public AccountObj(int Id, IService service)
    {
        _Id = Id;
        _service = service;
    }
    public double Amount { get; private set; }
    public void RefreshAmount()
    {
        Amount = _service.GetAmount(_Id);
    }
}
Run Code Online (Sandbox Code Playgroud)

如何对 的行为进行单元测试RefreshAmount

RefreshAmount调用IService.GetAmount可能会调用后端办公室,但我没有它的实现。任何关于去路的建议将不胜感激。(我已经阅读了关于 moq 和依赖注入,但我对单元测试很陌生)

Nko*_*osi 6

使用 Moq,这是一个带有注释的最小示例测试

[TestClass]
public class AccountObjUnitTests {
    [TestMethod]
    public void AccountObj_Given_Id_RefreshAmount_Should_Return_Expected_Amount() {

        //Arrange
        //creating expected values for test
        var expectedId = 1;
        var expectedAmount = 100D;
        //mock implementation of service using Moq
        var serviceMock = new Mock<IService>();
        //Setup expected behavior
        serviceMock
            .Setup(m => m.GetAmount(expectedId))//the expected method called with provided Id
            .Returns(expectedAmount)//If called as expected what result to return
            .Verifiable();//expected service behavior can be verified

        //the system under test
        var sut = new AccountObj(expectedId, serviceMock.Object);

        //Act
        //exercise method under test
        sut.RefreshAmount();


        //Assert

        //verify that expectations have been met
        serviceMock.Verify(); //verify that mocked service behaved as expected
        Assert.AreEqual(expectedAmount, sut.Amount);
    }

    //Samples class and interface to explain example
    public class AccountObj {
        private readonly int _Id;
        private readonly IService _service;
        public AccountObj(int Id, IService service) {
            _Id = Id;
            _service = service;
        }
        public double Amount { get; private set; }
        public void RefreshAmount() {
            Amount = _service.GetAmount(_Id);
        }
    }

    public interface IService {
        double GetAmount(int accountId);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是同一测试的更简化版本

[TestMethod]
public void AccountInfo_RefreshAmount_Given_Id_Should_Return_Expected_Amount() {
    //Arrange
    //creating expected values for test
    var expectedId = 1;
    var expectedAmount = 100D;
    //mock implementation of service using Moq with expected behavior
    var serviceMock = Mock.Of<IService>(m => m.GetAmount(expectedId) == expectedAmount);
    //the system under test
    var sut = new AccountObj(expectedId, serviceMock);

    //Act
    sut.RefreshAmount();//exercise method under test

    //Assert
    Assert.AreEqual(expectedAmount, sut.Amount);//verify that expectations have been met
}
Run Code Online (Sandbox Code Playgroud)