【问题标题】:Remove method attributes from mocked objects in C#从 C# 中的模拟对象中删除方法属性
【发布时间】:2016-09-21 18:44:56
【问题描述】:

我正在测试一个类的方法。但是,其中一些具有执行无关内容的属性,这会使测试失败。

例如,我有这个类(在VB.net,但也可以是C#

<AttributeOne()>
<AttributeTwo(Arg1, Arg2)>
Public Overridable Function SomeMethod() As Object
   ' Stuff
End Function

当我从我的模拟对象调用SomeMethod 时,它会引发一些异常,因为属性会尝试做一些在单元测试上下文中不可能的事情。

[TestFixture]
public class SomeClassUnitTests
{
    [Test]
    public void TestSomeMethod()
    {
        var someClassMock = new Mock<SomeClass>() { CallBase = true };

        //Exception is thrown
        var result = someClassMock.Object.SomeMethod();
    }
}

测试用C# 编写。我正在使用MoqNunit

如何在单元测试时忽略这些属性?

【问题讨论】:

  • 如果是这种情况,您就违反了单一责任原则。当您应该解决原因时,您正在尝试治疗症状。
  • @HimBromBeere 我正在测试SomeMethod,并且此方法具有一些评估全局安全信息的属性(例如用户是否已登录等)。但是,在单元测试中没有这样的信息,所以测试失败,我无法测试方法,明白了吗?
  • @DavidL 你能详细说明一下吗?
  • @RafaelCardoso 您不能忽略属性,但似乎您可以更改属性值Remove C# attribute of a property dynamically,也许您可​​以将值更改为允许您编写单元测试的值。
  • 你为什么要创建一个 SomeClass 的 Mock,然后在该 mock 上调用一个方法来测试该方法?只有当您想将其作为依赖项提供给某个 other 类时,您才应该 Mocking SomeClass,因为您正在测试 other 类并希望控制测试期间的依赖关系。在这种情况下,这些属性甚至不会发挥作用,因为 Mocked SomeClass 实际上并不是真正的 SomeClass。你能发布你得到的例外吗?

标签: c# .net vb.net unit-testing moq


【解决方案1】:

我想我明白你在这里想要做什么,但它不适用于 Mocks,因为即使你创建了一个 Mock SomeClass,你也必须模拟 SomeMethod 函数 - 你可以不要使用真正的!

这意味着你没有测试它,只是测试它的模拟版本。

但是,为什么不尝试不使用 Mocks 呢?

您可以将SomeOtherMethod 设为虚拟,然后将SomeClass 子类化以用于此测试。 然后,您可以编写任何您喜欢的 SomeOtherMethod 函数的覆盖;当你调用真正的SomeClass.SomeMethod 时,它会调用那个被覆盖的版本。

即(抱歉,在 C# 中这样做,因为我的 VB 生锈了)假设 SomeClass 看起来像这样,故意选择一个无用的功能以免混淆:

public class SomeClass
{
    public virtual int SomeMethod()
    {
      return SomeOtherMethod() / 2;
    }

    protected virtual SomeOtherMethod()
    {
        return [some crazy maths]
    }
}

您想测试 SomeMethod 是否正确返回了 SomeOtherMethod 的一半。

所以现在你可以在测试项目中这样做了:

public class SomeClassTestDouble: SomeClass
{
    protected override int SomeOtherMethod()
    {
         return 2;
    }
}

然后在你的测试中:

var sut = new SomeClassTestDouble();
var expected = 1;
var actual = sut.SomeMethod();
Assert.Equal(expected, actual)

现在您已经测试了SomeMethod 按预期工作,没有任何 Mocking。确实很多人会争辩说,除非您跨越架构或系统边界,否则您更喜欢测试替身(包括存根)而不是 Mocks。我一般不会说我是否同意,但在这种情况下,我认为最好不要模拟。

属性说明

请记住。属性 - 在系统的其他部分告诉他们做某事之前,他们不应该做任何事情。如果系统的那部分没有运行(即在测试期间),那么这些属性应该是完全惰性的。如果不是,那么我会倾向于查看您的单元测试项目,并确保您不会意外运行“实时”的东西,例如运行时安全框架或其他东西

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 2012-02-29
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多