我正在對遺留代碼(這裏是指「沒有單元測試的代碼」)進行一些測試。有時會遵循好的做法,但通常不會。儘管如此,我還是無法弄清楚在這種情況下需要做些什麼。Moq:嘲笑一個具有多重繼承的類
我需要能夠在具體的類中測試我想要的方法,但一直不能,因爲在我測試的類的構造函數中,它不僅具有我可以模擬的接口參數,而且它也從另一個具有自己的依賴關係的基類繼承。
我想測試的方法是FilterController.SomeMethod(whatever_params)。 FilterController繼承自BaseController。我已經添加了一個簡單的IFilterController接口,使FilterController繼承了BaseController和IFilterController。我在界面中唯一的方法是我想測試的方法(「SomeMethod」)。
現在,FilterController的構造函數就是我在跳轉到BaseController時遇到的問題。
public interface IFilterController { ActionResult SomeMethod(string s, bool b) }
public class FilterController : BaseController, IFilterController {
public FilterController(IFoo1 foo1, IFoo2 foo2, IFoo3 foo3, IFoo4 foo4)
: base(typeof(FilterController), foo1, foo2, foo3, foo4) {}
public ActionResult SomeMethod(string s, bool b) { // implementation }
// and the BaseController...
public BaseController(Type type, IFoo1 foo1, IFoo2 foo2, IFoo3 foo3, IFoo4 foo4)
{
// call that blows up due to not knowing how to mock the call inside here
_somePrivateProperty = _someOtherInterface.someCallThatIsntMocked(some_params)
// other stuff
}
我現在有想安裝的單元測試(MSTest的具有FluentAssertions和MOQ)代碼:
private FilterController filterController;
private Mock<IFilterController> filterControllerMock;
private Mock<IFoo1> foo1mock;
private Mock<IFoo2> foo2mock;
private Mock<IFoo3> foo3mock;
private Mock<IFoo4> foo4mock;
[ClassInitialize]
public static void ClassInit(TestContext context) {}
[TestInitialize]
public void Initialize()
{
filterControllerMock = new Mock<IFilterController>();
foo1mock = new Mock<IFoo1>();
foo2mock = new Mock<IFoo2>();
foo3mock = new Mock<IFoo3>();
foo4mock = new Mock<IFoo4>();
// here is where the test bombs out with exceptions due to the base class making calls to stuff not mocked
filterController = new FilterController(foo1mock.Object, foo2mock.Object, foo3mock.Object, foo4mock.Object);
}
[TestCleanup]
public void Cleanup(){}
[ExpectedException(typeof(CustomException))]
[TestMethod]
public void SomeMethod_ForcedErrorScenario_CatchesCustomException()
{
// Arrange
filterControllerMock
.Setup(x => x.SomeMethod(It.IsAny<string>(), It.IsAny<bool>()))
.Returns(new CustomException());
// Act
var result = filterController.SomeMethod("Foobar", false);
}
在這種情況下,是我確保被處理的try catch塊當它到達catch塊以確認錯誤得到修復時,應該正確。我不在乎爲了測試的目的而拋出異常,只是它被捕獲並且做了我期望的事情。然而,正如我所說的,我不能過去試圖模擬FilterController構造函數本身來調用其具體方法,因爲它繼承了BaseController。
- 編輯:解決了這個問題。在BaseController中,_someOtherInterface是基於在構造函數中傳遞的接口之一實例化的。在我的MSTest Initialize方法中,我只需要讓接口不會是空引用,然後使用安裝程序(x => x.otherMethod())覆蓋它調用的方法。返回(_someOtherInterface.Object)。
真正的應用程序如何實例化_someOtherInterface?它沒有被注入。看起來你需要重構它才能正常工作。 – Jonesopolis
我只是想出了那部分。它需要構造函數中傳遞的接口之一來調出並實例化其他接口。我只需在Initialize方法中添加一個調用來設置該模擬接口來覆蓋它所調用的方法。我會更新OP,但原來的問題已解決。實際上,這個新問題與原始問題相去甚遠,我寧願爲它創建一個新線程。我會解開它一段時間,看看我是否可以自己先弄明白。 – user1709953
很高興聽到您正在取得進展 – Jonesopolis