使用 Action<T> 模拟方法

我是单元测试的新手,很高兴知道我是否犯了任何错误或没有朝着正确的方向前进。


这是情况:


我正在尝试测试一个方法(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);

 }

我想知道???在测试中发生了什么,或者对于这个问题是否有完全不同的方法?


蝴蝶不菲
浏览 159回答 2
2回答

撒科打诨

我的第一直觉是重构ClassUnderTest并IInterface使其IInterface具有 get 属性,以便您完全删除 IInterface 实现的依赖项,而 MyClass 只有一项工作要做(存储 SampleString):interface IInterface{&nbsp; &nbsp; string SampleString { get; }}// Fix MyClassclass MyClass : IInterface{&nbsp; &nbsp; public string SampleString => "Hello There"}class ClassUnderTest{&nbsp; &nbsp; public string MethodUnderTest(IInterface someObject)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; string stringToBeTested = string.Empty;&nbsp; &nbsp; &nbsp; &nbsp; if (someObject.SampleString.Contains("."))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stringToBeTested = string.Empty;&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stringToBeTested = str.Replace(" ", string.Empty);&nbsp; &nbsp; &nbsp; &nbsp; return stringToBeTested;&nbsp; &nbsp; }}所以我们可以完全删除 Action 并且代码在测试时更具可读性和更容易遵循。只是另一种看待问题的方式。
打开App,查看更多内容
随时随地看视频慕课网APP