Макет виртуальных методов, а не симуляция переопределенных этих методов с Moq

В приведенном ниже коде я хочу смоделировать работу БД 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 ответ

Если вы можете разделить свою логику на другой метод (который также может быть лучше), чем вы можете использовать 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);
  }
}
Другие вопросы по тегам