App*_*lus 108 c# unit-testing moq
给出以下界面:
public interface IFoo
{
bool Foo(string a, bool b = false);
}
Run Code Online (Sandbox Code Playgroud)
试图用Moq模拟它:
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);
Run Code Online (Sandbox Code Playgroud)
在编译时出现以下错误:
表达式树可能不包含使用可选参数的调用或调用
我发现上面的问题是Moq问题列表中的一个增强,它似乎被分配到4.5版本(无论何时).
我的问题是:鉴于上述内容不会很快得到解决,我该怎么办?我的选项是否只是在每次模拟它时显式设置可选参数的默认值(哪种类型在第一时间指定一个失败)或创建没有bool的重载(就像我会做的那样)在C#4之前)?
或者有没有人遇到过更聪明的方法来克服这个问题?
Chr*_*tle 83
我相信你现在唯一的选择是明确地bool在设置中包含参数Foo.
我不认为它违背了指定默认值的目的.默认值是调用代码的便利,但我认为您应该在测试中明确.假设您可以省略指定bool参数.如果在未来,有人改变的默认值会发生什么b来true?这将导致失败的测试(这是理所当然的),但他们会因为隐藏的假设,即更难以解决b的false.明确指定bool参数还有另一个好处:它提高了测试的可读性.经过它们的人会很快知道有一个Foo函数可以接受两个参数.这是我的2美分,至少:)
至于每次模拟时都指定它,不要复制代码:在函数中创建和/或初始化模拟,这样你只有一个变化点.如果你真的想要,你可以通过将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
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
使用 Moq 版本 4.10.1 我已经能够做到以下几点
带接口:
public interface IFoo
{
bool Foo(string a, bool b = false);
}
Run Code Online (Sandbox Code Playgroud)
和模拟
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>(), It.IsAny<bool>())).Returns(false);
Run Code Online (Sandbox Code Playgroud)
使用第一个参数可以解析对 Foo 的调用
刚刚遇到这个问题,Moq不支持这个用例.因此,对于这种情况,似乎重写该方法就足够了.
public interface IFoo
{
bool Foo(string a);
bool Foo(string a, bool b);
}
Run Code Online (Sandbox Code Playgroud)
现在两种方法都可用,这个例子可行:
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45550 次 |
| 最近记录: |