1

我有这个代码:

    [TestMethod]
    public void TestMethod()
    {
        TextBox txtBox= new TextBox() { Text = "Test" };

        PrivateObject privateObj= new PrivateObject(someObject);
        var mockObj = new Mock<PrivateObject>();
        mockObj.Setup(x => x.Invoke("SomeMethod", It.IsAny<string>())).Returns(true);

        object result = privateObj.Invoke("DoSomething", txtBox, EventArgs.Empty);

        Assert.AreEqual(txtBox.Text, string.Empty);
    }

“DoSomething”方法调用“SomeMethod”方法,该方法返回一个布尔类型。我如何模拟 SometMetod,这样当我调用它时,他会返回我需要的东西?

4

1 回答 1

1

对不起,我应该更彻底地调查你的问题。我没有意识到这PrivateObject是一个已经存在的 .NET 框架类。

我的回答不会直接回答你的问题,但无论如何我都会把它留在这里。我假设您使用 Moq,因此类的以下部分不可用于模拟:

  • 非虚拟成员
  • 静态成员
  • 扩展方法
  • 密封类的任何成员
  • 字段

私人成员可以测试,我并不是说它通常是错误的。但是,通常需要测试私有成员是糟糕的代码设计的标志。

私有方法和字段是实现细节,不应影响您的类的功能。不要将每个方法视为一个单元,而是将类视为一个单元。测试你的班级的行为,它会做它应该做的事情,而不是测试它是如何做的。

对象结果 = privateObj.Invoke("DoSomething", txtBox, EventArgs.Empty); 您正在调用DoSomething方法,privateObj而不是mockObj设置返回“需要”的方法。

你的单元测试应该达到什么目的?模拟被测系统的行为有点矛盾,因为测试结果不能代表系统的实际行为。

我想您可以做的是将 from 的功能提取SomeMethodPrivateObject它的依赖项中,比如说IHaveSomeMethod.

public interface IHaveSomeMethod {
    bool SomeMethod();
}

public class PrivateObject {
    private IHaveSomeMethod dependency;

    public PrivateObject(???SomeObject someObject???, IHaveSomeMethod ihsm) {
        // ...
        this.iHaveSomeMethod = ihsm;
        // ...
    }

    public void DoSometing() {
        // ...
        iHaveSomeMethod.SomeMethod();
        // ...
    }
}

然后你可以像这样测试

[TestMethod]
public void TestMethod()
{
    TextBox txtBox= new TextBox() { Text = "Test" };

    var mockObj = new Mock<IHaveSomeMethod>();
    mockObj.Setup(x => x.Invoke("SomeMethod", It.IsAny<string>())).Returns(true);

    var sut = new PrivateObject(???someObject???, mockObj.Object); // system under test
    object result = sut.Invoke("DoSomething", txtBox, EventArgs.Empty);

    Assert.AreEqual(txtBox.Text, string.Empty);
}

于 2017-03-13T09:00:45.383 回答