C# Moq 模拟部分方法但抛出 NotSupportedException

问题描述

我关注了这个问题 Using Moq to mock only some methods 但仍然抛出了一个异常。

这是我的主要课程。 Foo 充当装饰器。

public class Foo {
    public Bar _b {get; set;}

    public Foo(Bar b) {
        this._b = b;
    }

    public bool MyMethod(){
        
        return ComplexMethod(_b.name);
    }

    public bool ComplexMethod(){
        ...
    }
}

测试类

[TestClass]
public class Foo {
    [TestMethod]
    public void TestFoo() {
        var b = new Bar() {name = "name"};
        var mock = new Mock<Foo>(b);
        mock.CallBase = true;
        mock.Setup(x => x.ComplexMethod()).Returns(true);
        var result = mock.Object.MyMethod();
        ...
    }
}

抛出异常:

System.NotSupportedException: '不支持的表达式:x => x.ComplexMethod() 不可覆盖的成员(此处:Foo.ComplexMethod) 不能在设置/验证表达式中使用。'

解决方法

您应该模拟依赖项而不是实际对象。因此,如果您想评估 MyMethodFoo,那么您应该模拟 Bar

为了能够模拟Bar的{​​{1}}成员:

  • 您应该将其标记为 namevirtual (ref)
  • 或者你应该定义一个接口

让我们看看后一种情况:

abstract

使用此设置,您的单元测试可能如下所示:

public interface IBar
{
   string Name { get; }
}

public class Bar: IBar
{
   public string Name { get; set; }
}

public class Foo 
{
    private readonly IBar _b;
    
    public Foo(IBar b) {
        this._b = b;
    }
    ...
}
[TestMethod]
public void GivenABar_WhereTheNameIsEmpty_WhenICallMyMethod_ThenItReturnsTrue() 
{
    //Arrange
    var barMock = new Mock<IBar>();
    barMock.SetupGet(x => x.Name).Returns("");

    //Act
    var SUT = new Foo(barMock.Object);
    var result = SUT.MyMethod();

    //Assert
    barMock.VerifyGet(m => m.Name,Times.Once);
    Assert.True(result);
}

UPDATE:模拟 SUT 的一种方法

如果您只想模拟 only[TestMethod] public void GivenABar_WhereTheNameIsNotEmpty_WhenICallMyMethod_ThenItReturnsFalse() { //Arrange var barMock = new Mock<IBar>(); barMock.SetupGet(x => x.Name).Returns("test"); //Act var SUT = new Foo(barMock.Object); var result = SUT.MyMethod(); //Assert barMock.VerifyGet(m => m.Name,Times.Once); Assert.False(result); } ComplexMethod,那么您可以使用 moq 的 Foo

As

请注意,此技术仅在 const bool expectedResult = true; var fooMock = new Mock<Foo>(barInstance).As<IFoo>(); fooMock.Setup(f => f.ComplexMethod()).Returns(expectedResult); 实现 Foo 时才有效,IFoo 也公开了

ComplexMethod

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...