WPF /.NET:我能不能用假的模拟完全代替具体类呢?

本文关键字:模拟 NET 能不能 WPF | 更新日期: 2023-09-27 18:10:55

我有一个大型的遗留WPF应用程序,它没有进行单元测试,并且到处都是大量的依赖项。我试图使用Moq来创建单元测试,但它并没有帮助我太多,当这么多(=几乎所有)类在内部创建依赖关系时,所以我没有办法注入我的模拟对象而不是真正的引用。

在c++中,你可以只编写自己的假类,并确保它们在测试项目中包含在真正的类之前——>这样整个项目中的所有引用都可以引用假对象,包括所有内部引用。

在。net中没有办法实现相同的功能吗?

提前感谢您的任何建议!

-Seppo

注:这是之前的问题NUnit/Moq的后续:我已经模拟了一个类,但真正的构造函数被执行,为什么?

WPF /.NET:我能不能用假的模拟完全代替具体类呢?

Microsoft Shims and Fakes应该做你想做的事情,但它只在Visual Studio Ultimate和Premium上可用。

除了MS Fakes/Shims之外,c#中没有任何现成的东西(或者我所知道的任何免费库)可以做你想要的。

您可以做的是使用"部分模拟"。假设你的类A在一个测试不友好的构造中创建了类B的一个实例,例如一个私有方法。

你可以移动新的ClassB()到一个工厂方法protected virtual方法CreateClassB(…),然后使用Moq的CallBase。

所以如果你在测试ClassA的MethodA

[Test]
public void MethodA_StateThatYouAreTesting_ExpectedResult()
{
    var partialMockA = new Mock<ClassA>{CallBase=true};
    var stubB = new Mock<ClassB>();
    stubB.Setup(b => b.SomeMethod()).Returns(SomeValue);
    parialMockA.Setup(a => a.CreateClassB()).Returns(stubB.Object);
    var result = partialMock.MethodA();
    Assert.AreEqual(someExpectedValue, result);
}

这省去了为ClassB创建接口的额外步骤。我相信在您继承的代码结构不太好的情况下,这是合理的,并且ClassB实际上应该分解为几个类和相应的接口(即,不遵循单一职责原则)。我喜欢把这看作是重构的第一步。

同样,Fakes的另一种替代方法是TypeMock。从来没有使用过它,但是因为它来自Roy Osherove(写了the Art of Unit Testing的家伙),所以它可能是一个安全的选择。