c# - 如何模拟具有参数的异步保护方法?

标签 c# unit-testing asynchronous moq protected

这是我要测试的类(class):

namespace ClassLibrary1
{
    public class MyBase
    {
        public async Task DoSomething (MyContext context) => await DoSomethingInternal (context);
        public async Task DoSomething() => await DoSomethingInternal();

        protected virtual async Task DoSomethingInternal(MyContext context) { }
        protected virtual async Task DoSomethingInternal() { }
    }

    public class MyContext { }

    public class MyClass : MyBase
    {
        protected override Task DoSomethingInternal(MyContext context) => Task.CompletedTask;
        protected override Task DoSomethingInternal() => Task.CompletedTask;
    }
}

这是测试代码:

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        [ExpectedException(typeof(TaskCanceledException))]
        public async Task TestMethod1()
        {
            var mock = new Mock<MyClass>
            {
                CallBase = true
            };
            mock.Protected().Setup<Task>("DoSomethingInternal", new MyContext()).ThrowsAsync(new TaskCanceledException());
            var obj = mock.Object;

            await obj.DoSomething(null);
        }

        [TestMethod]
        [ExpectedException(typeof(TaskCanceledException))]
        public async Task TestMethod2()
        {
            var mock = new Mock<MyClass>
            {
                CallBase = true
            };
            mock.Protected().Setup<Task>("DoSomethingInternal").ThrowsAsync(new TaskCanceledException());
            var obj = mock.Object;

            await obj.DoSomething();
        }
    }
}

结果显示第一次测试失败,第二次成功。调试显示第一个测试调用 DoSomethingInternal(context) 返回 Task.CompletedTask,而不是抛出异常。

那么我怎样才能让它抛出呢?

最佳答案

设置中传递的参数与执行测试时传递的实例不匹配。在这种情况下,您需要使用参数匹配器以允许代码按预期流动。

Setting expectations for protected members, if you need argument matching, you MUST use ItExpr rather than It

var mock = new Mock<MyClass>() {
    CallBase = true
};

mock.Protected()
    .Setup<Task>("DoSomethingInternal", ItExpr.IsAny<MyContext>())
    .ThrowsAsync(new TaskCanceledException());

var obj = mock.Object;

await obj.DoSomething(null);

引用 Moq Quickstart: Miscellaneous

关于c# - 如何模拟具有参数的异步保护方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53021329/

相关文章:

javascript promise 示例与 bluebird 跳过 "then"

c# - 为什么程序集的调用会占用如此多的 RAM?

java - 如何在不测试调用数据库的私有(private)方法的情况下进行单元测试

ios - 如何在 Swift 中使用 XCAssert 检查 isViewLoaded?

使用 VS 测试专家进行 C++ 单元测试

返回 LINQ 时的 c# 异步

c# - 在 Azure 门户中的何处查找日志信息

c# - 使用 xpath 和 selenium 设置 facebook 评论

c# - 如何使用绑定(bind)源更新数据 GridView

javascript - 使用 deferred.resolve(value) 返回到我的 .then() 的值未定义