如何模拟具有参数的异步受保护方法?
Posted
技术标签:
【中文标题】如何模拟具有参数的异步受保护方法?【英文标题】:How can I mock an async protected method that has a parameter? 【发布时间】:2019-03-31 22:59:46 【问题描述】:这是我要测试的课程:
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
,而不是抛出异常。
那么我怎样才能让它抛出呢?
【问题讨论】:
【参考方案1】:设置中传递的参数与执行测试时传递的实例不匹配。在这种情况下,您需要使用参数匹配器以允许代码按预期流动。
为受保护的成员设置期望值,如果您需要参数匹配,您必须使用
ItExpr
而不是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
【讨论】:
就像一个魅力。非常感谢。以上是关于如何模拟具有参数的异步受保护方法?的主要内容,如果未能解决你的问题,请参考以下文章