我有一个条件语句,应该如下所示:
//...
if(_view.VerifyData != true)
{
//...
}
else
{
_view.PermanentCancellation.Cancel();
}
其中 PermanentCancellation 是 CancellationTokenSource 类型。
我想知道我应该如何在我的 _view 模拟中设置它。到目前为止所有的尝试都失败了:(而且我在谷歌上找不到一个例子。
任何指针将不胜感激。
我有一个条件语句,应该如下所示:
//...
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
as然后您可以在测试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
它是传入的,尽管该令牌中的内容不一定重要。