在C#单元测试中,如何等效于Java的Spy(而不是Mock)仅模拟类中的某些方法?

唐·拉米

在Java中,当我有一个调用其他类的静态方法的类时,我总是将其封装起来,这样我就可以测试它,而无需实际访问该真实资源。例如:

public class HasSomeStaticCall
{
    public HasSomeStaticCall()
    {
        this.something = callStaticThing();
    }

    protected String callStaticThing()
    {
        return SomeThirdParty.getFromStaticMethod();
    {
}

在Java中,我可以使用Spy代替,Mock然后使用除那个之外的所有实际方法。

例:

public void test()
{
    HasSomeStaticCall obj = Mockito.spy( HasSomeStaticCall.class );

    //Only mock this one method
    Mockito.doReturn( "SomeValue" ).when( obj ).callStaticThing();
}

我将如何在C#中执行此操作?(我使用的是.Net Framework 4.7.x,而不是.Net Core)

米哈伊尔·弗拉多夫(Mikhail Vladov)

使用C#模拟框架,您不会有像间谍这样的概念。您可以做的是创建一个模拟并将其安排为调用原始代码,在该原始代码中,调用静态方法的方法可以返回所需的值。您应该记住,免费的C#模拟框架仅适用于接口和虚拟方法。因此,如果您的情况是安排一个返回值的公共虚拟方法,那么可以这样做。下面的示例将使用免费版本的JustMock

HasSomeStaticCall obj = Mock.Create<HasSomeStaticCall>(Behavior.CallOriginal);
Mock.Arrange(() => obj.callStaticThing()).Returns("SomeValue");

var actual = obj.callStaticThing();

Assert.AreEqual("SomeValue", actual);

JustMock有一个商业版本,允许您模拟非公共方法,例如代码中的受保护方法。这种方法的安排如下所示:

HasSomeStaticCall obj = Mock.Create<HasSomeStaticCall>(Behavior.CallOriginal);

Mock.NonPublic.Arrange<string>(obj, "callStaticThingProtected").Returns("SomeValue");
var actual = obj.MethodThatCallsTheProtectedcallStaticThing();

Assert.AreEqual("SomeValue", actual);

当然,应该有一种方法来调用受保护的方法。这就是为什么我使用MethodThatCallsTheProtectedcallStaticThing的原因。但是,如果您有另一种执行此方法的方法,则不需要此方法。

我注意到,在您的方案中,实际上是使用调用静态方法的方法的结果来设置构造函数中字段的值。大多数C#模拟框架将为您提供三个可能的选项来处理构造函数的执行:调用原始构造函数,不调用构造函数,而是执行其他操作而不是调用构造函数。它们都不允许您在创建模拟之前预先安排HasSomeStaticCall类的某些实例方法。这是一个问题,因为构造函数正在做您想保留的事情。JustMock允许您模拟静态方法。这是您的情况的示例:

Mock.Arrange(() => SomeThirdParty.getFromStaticMethod()).Returns("SomeValue");

HasSomeStaticCall obj = new HasSomeStaticCall();
var actual = obj.Something;

Assert.AreEqual("SomeValue", actual);

我已经创建了Something属性来访问该字段的值,如果您有另一种方法可以在需要时验证该值,则不需要该属性。

如果您对JustMock感兴趣,可以查看JustMock和JustMock Lite的功能比较表

免责声明 我是负责JustMock的开发人员之一

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Angular单元测试中,如何模拟整个组件而不是仅模拟类?

在python单元测试中模拟类和类方法

c# - 如何单元测试抽象类中的内部方法或私有方法?

等效于python3单元测试中的Proxyquire

如何在Python单元测试中模拟类?

在C#中模拟StreamReader以进行单元测试

如何在类方法中模拟python的datetime.now()进行单元测试?

如何在Angular中模拟父类方法进行单元测试?

如何在异步单元测试中模拟方法?

如何在模拟方法中对函数进行单元测试

如何在单元测试中模拟方法的结果?

在仪器单元测试中模拟方法

使用Mock对C#中的更新方法进行单元测试

您如何在C#中模拟文件系统以进行单元测试?

如何在单元测试C#中模拟AuthenticationContext.AcquireTokenAsync

如何使用 Visual Studio 单元测试框架或 NUnit 框架在 C# 中模拟对象?

如何使用C#中的Microsoft Fakes访问静态类专用字段以对其方法进行单元测试

等效于C#中的Java包

如何为python单元测试提供模拟类方法?

c#中单元测试的问题

如何忽略Pycharm 2017.1中的某些单元测试测试?

快速地在快速单元测试中模拟静态类方法?

有什么方法可以模拟结构以在单元测试中获得类?

如何使用Moq框架在C#中编写私有方法的单元测试?

如何在C#中为创建方法编写单元测试?

模拟函数不会在C#单元测试中引发异常

在单元测试中模拟Spring Controller方法模型绑定

在单元测试中模拟SignalR Clients.Group的方法

在python单元测试中模拟类属性的更好方法