从C#中的模拟对象中删除方法属性
我正在测试类的方法。但是,其中一些具有非相关内容的属性,这使得测试失败。从C#中的模拟对象中删除方法属性
例如,我有这个类(在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#
。我正在使用Moq
和Nunit
如何在单元测试时忽略这些属性?
我想我明白你要在这里做什么,但它不适用于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上的测试双打(包括存根)。我不会说如果我同意或不一般,但在这种情况下,我认为最好不要模仿。
注意事项
请记住re。属性 - 他们不应该做任何事情直到系统的其他部分告诉他们做某件事。如果系统的这一部分没有运行(即在测试过程中),那么这些属性应该是完全惰性的。如果他们不是,那么我倾向于看看你的单元测试项目,并确保你不会意外地运行诸如运行时安全框架之类的“实时”内容或其他东西
如果这样,你违反了单一责任原则是这样的。当您应该解决原因时,您正试图治疗症状。 –
@HimBromBeere我正在测试'SomeMethod',并且此方法具有一些评估全局安全信息的属性(例如,如果用户已登录并且有东西)。然而,在单元测试中没有这样的信息,所以测试失败了,我无法测试该方法,明白了吗? – RafaelC
@DavidL你能再详细一点吗? – RafaelC