unit-testing - 模拟虚拟方法而不是用 Moq 模拟覆盖此方法

标签 unit-testing moq xunit

在下面的代码中,我想在 FooBase 类中模拟 GetTitle(int id) 的数据库操作。但我想在覆盖的 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);
    }
}

最佳答案

如果您可以将您的逻辑分离到不同的方法中(这可能也是更好的设计),那么您可以使用 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);
  }
}

关于unit-testing - 模拟虚拟方法而不是用 Moq 模拟覆盖此方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48092875/

相关文章:

unit-testing - 如何使用Visual Studio 2015预览生成“智能单元测试”?

c# - 如何验证一个事件已经被模拟取消订阅

C# 如何模拟 Configuration.GetSection ("foo:bar").Get<List<string>>()

c# - 使用数据流调用起订量验证方法

f# - 自定义 FsCheck 任意类型在 Xunit 中损坏,但在 LINQPad 和常规 F# 程序中工作

c# - 犀牛模拟 : AssertWasCalled doesn't work on Stub

android - "gradlew connectedCheck mergeAndroidReports"缺少属性异常 : No such property: REPORTS

node.js - Expect(spiedMethod).not.toBeCalled() 失败,因为它正在被另一个测试调用

c# - 如何在 IHttpModule 中测试 HttpApplication 事件

c# - 只有 1 个 Main 方法的 XUnit 测试项目 : "Program has more than one entry point defined."