I have a conditional statement which should looks as follows:
//...
if(_view.VerifyData != true)
{
//...
}
else
{
_view.PermanentCancellation.Cancel();
}
where PermanentCancellation is of type CancellationTokenSource.
Im wondering how i should set this up in my mock of _view. All attempts thus far have failed :( and i cant find an example on google.
Any pointers would be appreciated.
I went a step further and made a factory to create a CancellationTokenManager class that implements the interface. This was because my method has to take CancellationToken and I wanted granular control over .IsCancellationRequested():
My CancellationTokenManagerFactory:
public interface ICancellationTokenManagerFactory
{
ICancellationTokenManager CreateManager(CancellationToken token);
}
public class CancellationTokenManagerFactory : ICancellationTokenManagerFactory
{
public ICancellationTokenManager CreateManager(CancellationToken token)
{
return new CancellationTokenManager(token);
}
}
and the manager:
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;
}
Then in a class utilizing:
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
}
}
}
Now if I check cancellation is requested more than once i can mock with different responses each time. Additionally, any interfaces like IHostService can still be utilized because CancellationToken is passed in although it doesn't necessarily matter what is in that token.
Because CancellationTokenSource.Cancel is not virtual you cannot mock it with moq.
You have two options:
Create a wrapper interface:
public interface ICancellationTokenSource
{
void Cancel();
}
and an implementation which delegates to the wrapped CancellationTokenSource
public class CancellationTokenSourceWrapper : ICancellationTokenSource
{
private readonly CancellationTokenSource source;
public CancellationTokenSourceWrapper(CancellationTokenSource source)
{
this.source = source;
}
public void Cancel()
{
source.Cancel();
}
}
And use the ICancellationTokenSource as PermanentCancellation then you can create an Mock<ICancellationTokenSource> in your tests:
// arrange
var mockCancellationTokenSource = new Mock<ICancellationTokenSource>();
viewMock.SetupGet(m => m.PermanentCancellation)
.Returns(mockCancellationTokenSource.Object)
// act
// do something
// assert
mockCancellationTokenSource.Verify(m => m.Cancel());
And use the CancellationTokenSourceWrapper in your production code.
Or use a mocking framework which supports mocking non virtual members like:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With