如何Moq一个方法,在其签名中有一个可选的参数,没有明确指定或使用重载?
鉴于以下界面:
public interface IFoo { bool Foo(string a, bool b = false); }
试图用Moq来嘲笑它:
var mock = new Mock<IFoo>(); mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);
在编译时给出以下错误:
expression式树可能不包含使用可选参数的调用或调用
我发现上面提到的问题是Moq问题清单中的一个增强 ,它似乎被分配到4.5版本(无论何时)。
我的问题是:我应该怎么做才能使上述问题不会很快得到解决呢? 我的select只是要么显式设置可选参数的默认值每次我嘲笑它(哪种破坏首先指定一个点)或创build一个没有bool的重载(就像我会做的在C#4之前)?
还是有人遇到更聪明的方法来解决这个问题?
我相信你现在唯一的select是在Foo
的设置中明确包含bool
参数。
我不认为它违背了指定默认值的目的。 默认值是调用代码的一个方便,但我认为你应该在你的testing中明确。 假设你可以不指定bool
参数。 如果将来有人将b
的默认值更改为true
,会发生什么情况? 这会导致testing失败(并且正确如此),但是由于隐藏的假设b
是false
,所以它们将更难以修复。 明确指定bool
参数还有另一个好处:它提高了testing的可读性。 有人通过他们会很快知道有一个Foo
函数接受两个参数。 这是我的2美分,至less:)
至于每当你嘲笑它时都指定它,不要复制代码:在一个函数中创build和/或初始化模拟,这样你只有一个改变点。 如果你真的想要的话,你可以通过将Foo
的参数复制到这个初始化函数中来克服Moq显然的短缺:
public void InitFooFuncOnFooMock(Mock<IFoo> fooMock, string a, bool b = false) { if(!b) { fooMock.Setup(mock => mock.Foo(a, b)).Returns(false); } else { ... } }
刚才遇到这个问题,Moq不支持这个用例。 所以,似乎凌驾于这种情况下的方法就足够了。
public interface IFoo { bool Foo(string a); bool Foo(string a, bool b); }
现在这两个方法都可用,这个例子可以工作:
var mock = new Mock<IFoo>(); mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);