在下面的示例中,我想测试TestMe.DoSomething()
函数。
我想模拟此方法中使用的ISomething
接口,并使其返回不同的值(取决于特定的单元测试。)
在现实生活中,ISomething
接口最终会调用昂贵的第三方资源-我绝对不想只调用真实的ISomething
。
这是示例结构:
class TestMe
{
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
private ISomething SomethingFactory()
{
return new Something();
}
}
interface ISomething
{
int Run();
}
class Something : ISomething
{
public int Run()
{
return 1;
}
}
这是无效的代码:
var fakeSomething = new Mock<ISomething>();
var testMe = new TestMe();
Mock.Get(testMe).Setup(p => p.SomethingFactory()).Returns(fakeSomething.Object);
testMe.DoSomething();
因为
SomethingFactory()
是private
,所以无法将该方法的返回值设置为所需的值。关于如何解决这个问题有什么建议吗?
最佳答案
使工厂成为完整的接口/类,并从TestMe中删除SomethingFactory方法。
public interface ISomethingFactory {
ISomething MakeSomething();
}
public sealed class SomethingFactory {
public ISomething MakeSomething() {
return new Something();
}
}
class TestMe
{
private readonly ISomethingFactory _somethingFactory;
public TestMe(ISomethingFactory somethingFactory) {
_somethingFactory = somethingFactory;
}
public void DoSomething()
{
ISomething s = _somethingFactory.MakeSomething();
int i = s.Run();
//do things with i that I want to test
}
}
这将允许您模拟ISomethingFactory以返回ISomething的模拟。
尽管我认为您可能会反对这种解决方案,因为它太过彻底了,但我认为它比制作一个没有被成员密封的课程要好得多,因为只有虚拟的原因是测试。