在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)
使用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的功能比较表
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句