[英]Providing an Implementation of an Interface for Moq to Use
假设我有以下设置:
public interface IFoo
{
string DoSomething();
string DoAnotherThing();
}
public sealed class Bar : IFoo
{
public string DoAnotherThing() => "DoAnotherThing";
public string DoSomething() => "DoSomething";
}
使用Moq,我想模拟Bar
一种方法,但是调用另一种方法。 我知道我可以通过创建一个委托给Bar
的包装类来实现这一点,如下所示:
public class MockableBar : IFoo
{
private readonly IFoo _bar;
public MockableBar(IFoo bar) => _bar = bar;
public virtual string DoAnotherThing() => _bar.DoAnotherThing();
public virtual string DoSomething() => _bar.DoSomething();
}
然后嘲笑它:
var fake = new Moq.Mock<MockableBar>(new Bar()) { CallBase = true };
fake.Setup(_ => _.DoSomething()).Returns("Mock");
Assert.AreEqual("DoAnotherThing", fake.Object.DoAnotherThing());
Assert.AreEqual("Mock", fake.Object.DoSomething());
有没有更通用的方法来实现这一点,所以我不必为我想在这个机制中测试的每个接口创建一个新的包装类?
我想你错过了一些观点。 没有必要使用mockablebar。 你可以直接模拟IFoo
接口。 (Mock也适用于虚方法和接口)。 你需要Bar
对象在哪里,实际上你应该使用IFoo
对象。 当你想测试bar类时,你的sut(被测系统)对象就是一个直接的吧。
注意:在测试期间,如果必须创建额外的类,这意味着您的代码不可测试。
如果代码中有这样的用法:
public void SomeFunction(Bar bar)
{
.... Do something
}
你可以改变这样(并且由于这个,你可以模拟参数并轻松编写测试fot方法)
public void SomeFunction(IFoo bar)
{
.... Do something
}
你的测试应该是这样的
Mock<IFoo> myMock = new Mock<IFoo>();
myMock.setup(m=>m.DoSomething()).Returns(()=>”some wantted result”);
//Or
myMock.setup(m=>m.DoSomething()).Throws(()=>new Exception(“some message”));
sut = new SomeClass();
sut.SomeFunction(myMock);
assert....
如果我正确理解你的问题,你有一个实现IFoo的Bar对象。 您正在测试的另一个对象取决于Bar,但您想要将Bar替换为假测试。
怎么样的:
// Arrange
Mock<IFoo> fooMock = new Mock<IFoo>();
fooMock.Setup(s => s.DoSomething()).Returns("Mock");
// using constructor injection, but hook up your IFoo implementer
// to your testObject however you normally would.
MyClass testObject = new MyClass(fooMock.Object);
// Act
testObject.DoSomethingInvokingIFooDoSomething();
// Assert whatever
你的MyClass对象需要使用IFoo而不是Bar来获取它的参数/变量等,因为它应该是解耦的,而不关心它的IFoo提供者如何提供结果,只是它可以。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.