模拟虚拟方法,而不是使用Moq模拟覆盖此方法

时间:2018-01-04 10:04:01

标签: unit-testing moq xunit

在下面的代码中,我想模拟GetTitle(int id)类中FooBase的数据库操作。但我想在重写GetTitle(int id)中测试验证部分。

我想测试重写方法但是模拟基本方法

我如何模拟虚拟方法并测试它的重写?

public abstract class FooBase
{
    public virtual string GetTitle(int id) { return "Title From DB" /*Select From DB*/; }
}

public class Foo : FooBase
{
    public override string GetTitle(int id)
    {
        if (id < 0)
            return "Invalid id";

        /*Doing somethings like other validations and etc*/

        return $"Valid ID ({base.GetTitle(id)})";
    }
}

public class FooTests
{
    [Fact]
    public void GetTitle() // Fails
    {
        // Arrange
        var expectedID = 1;
        var expectedResult = "Test";
        var fooMock = new Mock<Foo>();
        fooMock.Setup(x => x.GetTitle(It.IsAny<int>())).Returns(expectedResult);
        var foo = fooMock.Object;

        // Act
        var title = foo.GetTitle(expectedID);

        // Assert
        fooMock.Verify(x => x.GetTitle(It.Is<int>(c => expectedID == c)), Times.Once);
        Assert.Equal($"Valid ID ({expectedResult})", title);
    }
}

1 个答案:

答案 0 :(得分:1)

如果你可以将你的逻辑分成不同的方法(也可能是更好的设计),那么你可以使用Moq的CallBase属性来使测试调用模拟方法。

public abstract class FooBase
{
   public virtual string GetTitle(int id) { return "Title From DB" /*Select From DB*/; }
}

public class Foo : FooBase
{
  public virtual string GetValidatedTitle(int id)
  {
    if (id < 0)
    return "Invalid id";

    /*Doing somethings like other validations and etc*/

    return $"Valid ID ({GetTitle(id)})";
  }
}

public class FooTests
{
  [Fact]
  public void GetTitle() // Now Passes
  {
    // Arrange
    var expectedID = 1;
    var expectedResult = "Test";
    var fooMock = new Mock<Foo>() { CallBase = true };
    fooMock.Setup(x => x.GetTitle(It.IsAny<int>())).Returns(expectedResult);
    var foo = fooMock.Object;

    // Act
    var title = foo.GetValidatedTitle(expectedID);

    // Assert
    fooMock.Verify(x => x.GetTitle(It.Is<int>(c => expectedID == c)), Times.Once);
    Assert.Equal($"Valid ID ({expectedResult})", title);
  }
}