[英]Checking that CancellationTokenSource.Cancel() was invoked with Moq
我有一个条件语句,应该如下所示:
//...
if(_view.VerifyData != true)
{
//...
}
else
{
_view.PermanentCancellation.Cancel();
}
其中 PermanentCancellation 是 CancellationTokenSource 类型。
我想知道我应该如何在我的 _view 模拟中设置它。 到目前为止所有的尝试都失败了:(而且我在谷歌上找不到一个例子。
任何指针将不胜感激。
因为CancellationTokenSource.Cancel不是虚拟的,所以你不能用moq来模拟它。
您有两种选择:
创建一个包装器接口:
public interface ICancellationTokenSource
{
void Cancel();
}
以及委托给包装的CancellationTokenSource的实现
public class CancellationTokenSourceWrapper : ICancellationTokenSource
{
private readonly CancellationTokenSource source;
public CancellationTokenSourceWrapper(CancellationTokenSource source)
{
this.source = source;
}
public void Cancel()
{
source.Cancel();
}
}
并使用ICancellationTokenSource
作为PermanentCancellation
然后您可以在测试中创建Mock<ICancellationTokenSource>
:
// arrange
var mockCancellationTokenSource = new Mock<ICancellationTokenSource>();
viewMock.SetupGet(m => m.PermanentCancellation)
.Returns(mockCancellationTokenSource.Object)
// act
// do something
// assert
mockCancellationTokenSource.Verify(m => m.Cancel());
并在生产代码中使用CancellationTokenSourceWrapper
。
或者使用支持模拟非虚拟成员的模拟框架,例如:
我更进一步,做了一个factory
来创建一个实现接口的CancellationTokenManager
类。 这是因为我的方法必须采用CancellationToken
并且我希望对.IsCancellationRequested()
进行精细控制:
我的CancellationTokenManagerFactory
:
public interface ICancellationTokenManagerFactory
{
ICancellationTokenManager CreateManager(CancellationToken token);
}
public class CancellationTokenManagerFactory : ICancellationTokenManagerFactory
{
public ICancellationTokenManager CreateManager(CancellationToken token)
{
return new CancellationTokenManager(token);
}
}
和经理:
public interface ICancellationTokenManager
{
bool IsCancellationRequested { get; }
CancellationToken CancellationToken { get; }
}
public class CancellationTokenManager : ICancellationTokenManager
{
private readonly CancellationToken _token;
public CancellationTokenManager(CancellationToken token)
{
_token = token;
}
public bool IsCancellationRequested
{
get
{
return _token.IsCancellationRequested;
}
}
public CancellationToken CancellationToken => _token;
}
然后在课堂上使用:
public class MyService
{
private readonly ICancellationTokenManagerFactory _factory = factory;
public MyService(ICancellationTokenManagerFactory factory)
{
_factory = factory;
}
public void StartAsync(CancellationToken token)
{
manager = _factory.CreateManager(token);
//check if cancelled
if (!manager.IsCancellationRequested())
}
// do some work
}
}
}
现在,如果我多次检查取消请求,我可以每次都模拟不同的响应。 此外,仍然可以使用像IHostService
这样的任何接口,因为CancellationToken
已传入,尽管该令牌中的内容并不一定重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.