使用Moq模擬擴充法
在單元測試場景中,可能需要模擬應用於現有介面的擴展方法。考慮以下情況:
<code class="language-csharp">public interface ISomeInterface { void SomeMethod(); } public static class SomeInterfaceExtensions { public static void AnotherMethod(this ISomeInterface someInterface) { // 方法实现 } } public class Caller { private readonly ISomeInterface someInterface; public Caller(ISomeInterface someInterface) { this.someInterface = someInterface; } public void Main() { someInterface.AnotherMethod(); } }</code>
為了測試Caller
類,需要模擬ISomeInterface
介面並驗證對AnotherMethod
擴充方法的呼叫。但是,直接嘗試模擬x => x.AnotherMethod()
會產生異常:
<code class="language-csharp">[Test] public void Main_BasicCall_CallsAnotherMethod() { // Arrange var someInterfaceMock = new Mock<ISomeInterface>(); someInterfaceMock.Setup(x => x.AnotherMethod()).Verifiable(); // 这里会抛出异常 var caller = new Caller(someInterfaceMock.Object); // Act caller.Main(); // Assert someInterfaceMock.Verify(); }</code>
異常訊息:
<code>System.ArgumentException: Invalid setup on a non-member method: x => x.AnotherMethod()</code>
為了解決這個問題,一個方法是為擴充方法建立一個包裝器物件:
<code class="language-csharp">public class AnotherMethodWrapper { public static void CallAnotherMethod(ISomeInterface someInterface) { someInterface.AnotherMethod(); } }</code>
在測試中,可以模擬包裝器方法:
<code class="language-csharp">[Test] public void Main_BasicCall_CallsAnotherMethod() { // Arrange var wrapperMock = new Mock<AnotherMethodWrapper>(); wrapperMock.Setup(x => x.CallAnotherMethod(It.IsAny<ISomeInterface>())).Verifiable(); var someInterfaceMock = new Mock<ISomeInterface>(); // 这里需要调整Caller的构造函数,注入wrapperMock.Object // 这部分需要根据实际情况修改,可能需要修改Caller类或者使用其他方法注入依赖 var caller = new Caller(someInterfaceMock.Object); // 此处可能需要修改,注入wrapperMock.Object // Act caller.Main(); // Assert wrapperMock.Verify(); }</code>
透過使用包裝器,可以模擬擴展方法呼叫並進行單元測試。 需要注意的是,這個例子中的Caller
類別需要修改才能使用AnotherMethodWrapper
, 這取決於Caller
類別的具體實現,可能需要依賴注入或其他方式將AnotherMethodWrapper
注入到Caller
中。
以上是如何使用最小起訂量在單元測試中模擬擴充方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!