簡體   English   中英

使用Action模擬方法<T>

[英]Mocking a method with Action<T>

我是Unit Testing的新手,很高興知道我是否犯了錯誤或者沒有朝着正確的方向前進。

情況如下:

我正在嘗試測試一個方法( MethodUnderTest ),該方法調用另一個方法( MethodWithAction ),該方法將Action<T>作為參數。 我想模擬MethodWithAction ,但是根據返回值測試邏輯。

這是結構:

interface IInterface
{
    void MethodWithAction(Action<string> action);
}

class MyClass : IInterface
{
    public void MethodWithAction(Action<string> action)
    {
        string sampleString = "Hello there";
        action(sampleString);
    }
}

class ClassUnderTest
{
    public IInterface Obj = new MyClass();
    public string MethodUnderTest()
    {
        string stringToBeTested = string.Empty;

        Obj.MethodWithAction(str =>
        {
            if (str.Contains("."))
                stringToBeTested = string.Empty;
            else
                stringToBeTested = str.Replace(" ", string.Empty);
        });
        return stringToBeTested;
    }
}

我的測試方法是這樣的:

[TestMethod]
[DataRow("Hello, World", "Hello,World")]
[DataRow("Hello, World.","")]
[DataRow("Hello", "Hello")]
public void MethodUnderTestReturnsCorrectString(string sampleString, string expected)
{
    var mockObj = new Mock<IInterface>();
    mockObj.Setup(m=>m.MethodWithAction(It.IsAny<Action<string>>))
    .Callback(???);
    ClassUnderTest sut = new ClassUnderTest();
    sut.Obj=mockObj.Object;
    string actual = sut.MethodUnderTest();
    Assert.Equal(expected, actual);
 }

我想知道在什么地方??? 在測試中,還是有完全不同的方法來解決這個問題?

獲取在回調中傳遞給mock的action參數,並使用示例字符串調用它。

mockObj
    .Setup(m => m.MethodWithAction(It.IsAny<Action<string>>))
    .Callback((Action<string> action) => action(sampleString));

參考Moq Quickstart以更好地理解如何使用此模擬框架。

我的第一直覺是重構ClassUnderTestIInterface以便IInterface有一個get屬性,你可以完全刪除IInterface實現的依賴,而MyClass只有一個工作要做(存儲SampleString):

interface IInterface
{
    string SampleString { get; }
}

// Fix MyClass
class MyClass : IInterface
{
    public string SampleString => "Hello There"
}

class ClassUnderTest
{
    public string MethodUnderTest(IInterface someObject)
    {
        string stringToBeTested = string.Empty;

        if (someObject.SampleString.Contains("."))
            stringToBeTested = string.Empty;
        else
            stringToBeTested = str.Replace(" ", string.Empty);

        return stringToBeTested;
    }
}

因此,我們可以完全刪除Action,並且在測試時代碼更易讀,更容易理解。

只是看待問題的另一種方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM