[英]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.