从C#中的模拟对象中删除方法属性

时间:2016-09-21 18:44:57

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

我正在测试一个类的方法。但是,它们中的一些具有执行非相关内容的属性,这使得测试失败。

例如,我有这个课程(在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

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

1 个答案:

答案 0 :(得分:0)

我想我知道你在这里要做的是什么,但它不适用于Mocks,因为即使你创建了一个模拟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按预期工作而没有任何模拟。事实上,许多人会争辩说,除非你跨越建筑或系统边界,否则你更喜欢测试双打(包括存根)而不是Mocks。我不会说我是否同意,但在这种情况下,我认为最好不要模拟。

关于属性

的注释

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