【发布时间】:2015-12-21 19:01:20
【问题描述】:
假设我有一个带有(示例)实现的 WCF 服务:
public interface IFoo
{
void Bar();
void Baz();
}
public interface ISomeDependency
{
void DoStuff();
}
public class Foo : IFoo
{
ISomeDependency _someDependency;
public Foo(ISomeDependency someDependency)
{
this._someDependency = someDependency;
}
public void Bar()
{
// Some stuff
_someDependency.DoStuff();
if (1 == 1) // some condition that won't always be true
this.Baz();
}
public void Baz()
{
// some stuff
_someDependency.DoStuff();
}
}
如何在不关心Foo.Baz 的结果的情况下对Foo.Bars 实施进行单元测试?具体来说,我想知道 Foo.Baz();是否被调用取决于我如何模拟对Foo.Bar 的调用,但不一定希望Foo.Bazs 逻辑“触发”。
我原本打算做这样的事情:
public class Foo : IFoo
{
// ... same as previous
public virtual void Baz()
{
// some stuff
_someDependency.DoStuff();
}
}
然后在我的单元测试项目中:
public class TestFoo : Foo
{
public bool IsBazFired { get; private set; }
public TestFoo(ISomeDependency someDependency)
: base (someDependency)
{
IsBazFired = false;
}
public override void Baz()
{
IsBazFired = true;
}
}
这样我可以看到Foo.Baz 在我的测试中触发(尽管我必须使用TestFoo 而不是Foo 进行测试。还有其他方法可以解决这个问题吗?看起来工作量还不够现在,但如果试图在所有地方实现这一点,代码可能/将会变得到处都是类的测试实现。
我不一定喜欢将我的函数标记为virtual,这样我就可以为测试存根实现......所以我希望有另一种方式。
我目前刚刚开始使用模拟框架 Moq,如果这对如何实现我想要的结果有影响的话。
【问题讨论】:
-
您可以使用模拟框架,例如,FakeItEasy、NSubstitute。
-
就像 Sergii 所说,没有模拟框架,您必须像以前那样手动完成。
-
我目前正在使用(或尝试学习)
Moq,但还没有使用混凝土,只有接口模拟 -
如果您不想(或不能)使用
virtual,有一个模拟框架Microsoft Fakes 可以帮助您使用垫片测试几乎所有内容。A shim modifies the compiled code of your application at run time so that instead of making a specified method call, it runs the shim code that your test provides.
标签: c# unit-testing moq