Checking that CancellationTokenSource.Cancel() was invoked with Moq - c#

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.

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:
Microsoft Fakes
Typemock isolator (commercial)
JustMock (commercial)

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.

Related

Unable to cast object of type AsyncStateMachineBox System.Threading.Tasks.VoidTaskResult to type System.Threading.Tasks.Task

I'm very new to ASP.NET Web API and I'm trying to use Entity Framework Core's Dependency Injection to POST data to the API Controller using MediatR pattern. But every time I run my code and it opens Swagger UI, I get an error 500 response saying
Unable to cast object of type 'AsyncStateMachineBox1[System.Threading.Tasks.VoidTaskResult,S3E1.Repository.CartItemRepository+<Createitem>d__5]' to type 'System.Threading.Tasks.Task1[S3E1.Entities.CartItemEntity]'.
First, I added Dependency Injections to Program.cs
//Dependency Injection
builder.Services.AddDbContext<AppDataContext>(contextOptions => contextOptions.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")
));
//Connection
builder.Services.AddSingleton<DataConnectionContext>();
These are the classes.
AppDataContext.cs
public class AppDataContext : DbContext
{
public AppDataContext(DbContextOptions<AppDataContext> contextOptions) : base(contextOptions) { }
public DbSet<CartItemEntity> CartItems { get; set; }
public DbSet<OrderEntity> Orders { get; set; }
public DbSet<UserEntity> Users{ get; set; }
}
DataConnectionContext.cs
public class DataConnectionContext
{
private readonly IConfiguration _configuration;
private readonly string _connectionString;
public DataConnectionContext(IConfiguration configuration)
{
_configuration = configuration;
_connectionString = _configuration.GetConnectionString("DefaultConnection");
}
public IDbConnection CreateConnection() => new SqlConnection(_connectionString);
}
Next is making a repository which holds the interface that has the create method.
public interface ICartItemRepository
{
//public Task<IEnumerable<CartItemEntity>> GetCartItems();
//public Task<CartItemEntity> GetCartItemEntity(Guid id);
public Task Createitem(CartItemEntity itemEntity);
}
Then a class that inherits the interface and calls the dependency constructors
public class CartItemRepository : ICartItemRepository
{
private readonly DataConnectionContext _connectionContext;
private readonly AppDataContext _appDataContext;
public CartItemRepository(DataConnectionContext connectionContext, AppDataContext appDataContext)
{
_connectionContext = connectionContext;
_appDataContext = appDataContext;
}
public async Task Createitem(CartItemEntity itemEntity)
{
_appDataContext.CartItems.Add(itemEntity);
await _appDataContext.SaveChangesAsync();
await _appDataContext.CartItems.ToListAsync();
}
}
Next is a command for POST request MediatR pattern
public record AddCartItemCommand(CartItemEntity cartItem) : IRequest<CartItemEntity>;
and a Handler which manages and returns the method createitem
public class AddItemsHandler : IRequestHandler<AddCartItemCommand, CartItemEntity>
{
private readonly ICartItemRepository _cartItemRepository;
public AddItemsHandler(ICartItemRepository cartItemRepository) => _cartItemRepository = cartItemRepository;
public async Task<CartItemEntity> Handle(AddCartItemCommand request, CancellationToken cancellationToken)
{
return await (Task<CartItemEntity>) _cartItemRepository.Createitem(request.cartItem);
}
}
and lastly, in the controller
[Route("api/cart-items")]
[ApiController]
public class CartItemsController : ControllerBase
{
private ISender _sender;
public CartItemsController(ISender sender) => _sender = sender;
[HttpPost]
public async Task<CartItemEntity> Post(CartItemEntity cartItemEntity)
{
return await _sender.Send(new AddCartItemCommand(cartItemEntity));
}
}
I tried modifying the return object in the handler but every time I change anything it always get the error squiggly line, so I just casted the (Task) after the await. Is this where I went wrong? Thank you for any answers.
The exception is clear. You can't cast a VoidTaskResult to Task<CartItemEntity>.
To solve the problem:
In ICartItemRepository, modify the return type for Createitem as Task<CartItemEntity>.
In CartItemRepository, implement Createitem method from the ICartItemRepository interface. Return the inserted itemEntity in the method.
Since you have implemented Task<CartItemEntity> Createitem(CartItemEntity itemEntity) in the ICartItemRepository interface, the casting to (Task<CartItemEntity>) is no longer needed, and suggested to be removed.
public interface ICartItemRepository
{
...
public Task<CartItemEntity> Createitem(CartItemEntity itemEntity);
}
public class CartItemRepository : ICartItemRepository
{
...
public async Task<CartItemEntity> Createitem(CartItemEntity itemEntity)
{
_appDataContext.CartItems.Add(itemEntity);
await _appDataContext.SaveChangesAsync();
return itemEntity;
}
}
public class AddItemsHandler : IRequestHandler<AddCartItemCommand, CartItemEntity>
{
...
public async Task<CartItemEntity> Handle(AddCartItemCommand request, CancellationToken cancellationToken)
{
return await _cartItemRepository.Createitem(request.cartItem);
}
}

getting an error The following constructor parameters did not have matching fixture data: PostgreSqlResource resource

I am using xunit to do integration testing, and below is my test class.
public class CodesAndGuidelinesTest : IClassFixture<SchemaCache>
{
public readonly SchemaCache schemaCache;
public CodesAndGuidelinesTest(PostgreSqlResource resource)
{
schemaCache = new SchemaCache(resource);
}
[Fact]
public async Task Create_Name_Contains_Expression()
{
IRequestExecutor requestExecutor = await schemaCache.CodesAndGuidelinesExecutor;
.......
}
}
Here is the schema cache class
public class SchemaCache : QueryTestBase
{
Task<IRequestExecutor> _codesAndGuidelinesExecutor;
public SchemaCache(PostgreSqlResource resource) : base(resource)
{
_codesAndGuidelinesExecutor = CreateDb(CodesAndGuidelinesMockFixture.codeStandardGuidelines);
}
public Task<IRequestExecutor> CodesAndGuidelinesExecutor
{
get { return _codesAndGuidelinesExecutor; }
}
}
Here CodesAndGuidelinesMockFixture.codeStandardGuidelines is just a mock object, and When I run the test cases, I am getting the below error.
Class fixture type 'API.Tests.SchemaCache` had one or more unresolved
constructor arguments: PostgreSqlResource resource,
CodeStandardGuideline[] codesAndGuidelines The following
constructor parameters did not have matching fixture data:
PostgreSqlResource resource
I am not sure where I am doing wrong with the above code. Could anyone point me in the right direction?
Thanks!!!
Update :
QueryTestBase class
public class QueryTestBase
{
private readonly PostgreSqlResource _resource;
public QueryTestBase(PostgreSqlResource resource)
{
_resource = resource;
}
protected async Task<Func<IResolverContext, IQueryable<T>>> BuildResolverAsync<T>(T[] arrayOfEntities) where T : class
{
var databaseName = Guid.NewGuid().ToString("N");
var options = new DbContextOptionsBuilder<APIDbContext>()
.UseNpgsql(_resource.ConnectionString)
.Options;
.......
.......
return _ => set.AsQueryable();
}
protected async Task<IRequestExecutor> CreateDb<T>(T[] Entities) where T : class
{
Func<IResolverContext, IQueryable<T>> resolver = await BuildResolverAsync(Entities);
return .......
}
}
Your tool (Squadron) provides an easy way to have a PostgreSqlResource.
This resource has this properties:
implement standard IDisposable interface (or xunit speficIAsyncLifetime interface)
has a parameterless contructor
// sync implementation
class PostgreSqlResource : IDisposable
{
public PostgreSqlResource()
{
// init code
}
// props and logic
public Dispose()
{
// dispose code
}
}
// async implementation
class PostgreSqlResource : IAsyncLifetime
{
public PostgreSqlResource()
{
}
public async Task InitializeAsync()
{
// init code
}
// props and logic
public async Task DisposeAsync()
{
// dispose code
}
}
This object can be shared in xunit in 3 way:
for each test: create fixture, execute test, dispose fixture
for each class: create fixture, execute tests inside a class, dispose fixture
for a set of classes: create fixture, execute marked test classes, dispose fixture
In your case you need the 3rd way.
So Squadron provide a fixture for you, jou just need to define a TestCollection to mark your classes.
[CollectionDefinition("Squadron")]
public class DatabaseCollection : ICollectionFixture<PostgreSqlResource>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
and after that you can simply tag your test classes with attribute [Collection("Squadron")] that allow you in inject via constructor the shared instance.
[Collection("Squadron")]
public class DatabaseTestClass1
{
PostgreSqlResource fixture;
public DatabaseTestClass1(PostgreSqlResource fixture)
{
this.fixture = fixture;
}
}
[Collection("Squadron")]
public class DatabaseTestClass2
{
// ...
In case PostgreSqlResource is not enought and you need a more complex fixture is very easy; you can just create your own fixture around the other.
Of course you need to implement the same interface and delegate implementation to inner member.
class ComplexFixture: IAsyncLifetime
{
private PostgreSqlResource _pg;
public ComplexFixture()
{
_pg = new PostgreSqlResource();
}
// fixture methods
public async Task InitializeAsync()
{
await _pg.InitializeAsync();
}
public async Task DisposeAsync()
{
await _pg.DisposeAsync();
}
}
And refer to ComplexFixture insted of PostgreSqlResource on xunit CollectionFixtures. This approach is not suggested.
In my opinion is better a Plain fixture injected to test class, and than wrapped in a class fixture object if needed.
[Collection("Squadron")]
public class DatabaseTestClass1 : IDisposable
{
// each test lifecycle
private MyComplexFixture _fixture;
// global lifecycle
public DatabaseTestClass1(DatabaseFixture dbFixture)
{
_fixture = new MyComplexFixture(dbFixture)
}
// tests
public Dispose()
{
// this can reset db state for a new test
_fixture.Dispose();
}
}
public class MyComplexFixture : IDisposable
{
public MyComplexFixture (DatabaseFixture dbFixture)
{
// ...
}
public Dispose()
{
// reset logic like DROP TABLE EXECUTION
// Please note that dbFixture shoul no be disposed here!
// xunit will dispose class after all executions.
}
}
So applying this solution to your code can be as follows.
[CollectionDefinition("SquadronSchemaCache")]
public class DatabaseCollection : ICollectionFixture<SchemaCache>
{
}
[Collection("SquadronSchemaCache")]
public class CodesAndGuidelinesTest
{
public readonly SchemaCache schemaCache;
public CodesAndGuidelinesTest(SchemaCache resource)
{
this.schemaCache = schemaCache;
}
[Fact]
public async Task Create_Name_Contains_Expression()
{
IRequestExecutor requestExecutor = await schemaCache.CodesAndGuidelinesExecutor;
.......
}
}
public class SchemaCache : QueryTestBase
{
Task<IRequestExecutor> _codesAndGuidelinesExecutor;
public SchemaCache() : base(new PostgreSqlResource())
{
_codesAndGuidelinesExecutor = CreateDb(CodesAndGuidelinesMockFixture.codeStandardGuidelines);
}
public Task<IRequestExecutor> CodesAndGuidelinesExecutor
{
get { return _codesAndGuidelinesExecutor; }
}
}
public class QueryTestBase : IAsyncLifetime
{
private readonly PostgreSqlResource _resource;
public QueryTestBase(PostgreSqlResource resource)
{
_resource = resource;
}
protected async Task<Func<IResolverContext, IQueryable<T>>> BuildResolverAsync<T>(T[] arrayOfEntities) where T : class
{
var databaseName = Guid.NewGuid().ToString("N");
var options = new DbContextOptionsBuilder<APIDbContext>()
.UseNpgsql(_resource.ConnectionString)
.Options;
.......
.......
return _ => set.AsQueryable();
}
protected async Task<IRequestExecutor> CreateDb<T>(T[] Entities) where T : class
{
Func<IResolverContext, IQueryable<T>> resolver = await BuildResolverAsync(Entities);
return .......
}
public async Task InitializeAsync()
{
await _resource.InitializeAsync();
}
public async Task DisposeAsync()
{
_resource.Dispose()
}
}

How to create a xUnit test case for await _propertyRepository.UnitOfWork.SaveEntitiesAsync()?

How can I test return await _propertyRepository.UnitOfWork.SaveEntitiesAsync();?
AddCommandHandler
public async Task<bool> Handle(AddCommand message, CancellationToken cancellationToken)
{
_logger.LogInformation("----- Adding Property - Property: {#Property}", property);
_propertyRepository.Add(property);
return await _propertyRepository.UnitOfWork.SaveEntitiesAsync();
}
Anyone please guide me to write test case for that only. I am writing like this. But the test case fails.
PropertyRepository
public class PropertyRepository : IPropertyRepository
{
private readonly RealxContext _realxContext;
public IUnitOfWork UnitOfWork
{
get
{
return _realxContext;
}
}
public PropertyRepository(RealxContext realxContext)
{
_realxContext = realxContext ?? throw new ArgumentNullException(nameof(realxContext));
}
AddCommandHandlerTests.cs
_propertyRepository.Setup(propertyRepo => propertyRepo.UnitOfWork.SaveEntitiesAsync(default(CancellationToken))).Returns(Task.FromResult(true));

Execute hosted service in per request scope

I have a background service that runs every 30 seconds in my ASP .NET Core WebApi application. Its registered to the service container in ConfigureServices in Startup.cs by the line
services.AddSingleton<IHostedService, SimpleService>();
Then I have this class and its upper class to execute a given method every 30 seconds:
The general background service class:
public abstract class BackgroundService : IHostedService, IDisposable
{
private Task currentTask;
private readonly CancellationTokenSource stopCts = new CancellationTokenSource();
public virtual Task StartAsync(CancellationToken cancellationToken)
{
currentTask = ExecuteAsync(stopCts.Token);
if (currentTask.IsCompleted)
return currentTask;
return Task.CompletedTask;
}
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
if (currentTask == null)
return;
try
{
stopCts.Cancel();
}
finally
{
await Task.WhenAny(currentTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
protected virtual async Task ExecuteAsync(CancellationToken cancellationToken)
{
DateTime nextExecution = DateTime.Now;
do
{
DateTime currentTime = DateTime.Now;
if (nextExecution <= currentTime)
{
nextExecution = currentTime.Add(TimeSpan.FromSeconds(30));
await Process(cancellationToken);
}
else
{
await Task.Delay(nextExecution - currentTime, cancellationToken);
}
}
while (!cancellationToken.IsCancellationRequested);
}
protected abstract Task Process(CancellationToken cancellationToken);
public void Dispose()
{
stopCts.Cancel();
}
}
The one to use when a specific scope is needed:
public abstract class ScopedBackgroundService : BackgroundService
{
private readonly IServiceScopeFactory serviceScopeFactory;
public ScopedBackgroundService(IServiceScopeFactory serviceScopeFactory)
{
this.serviceScopeFactory = serviceScopeFactory;
}
protected override async Task Process(CancellationToken cancellationToken)
{
using (var scope = serviceScopeFactory.CreateScope())
{
await ProcessInScope(scope.ServiceProvider, cancellationToken);
}
}
public abstract Task ProcessInScope(IServiceProvider serviceProvider, CancellationToken cancellationToken);
}
When implementing the service itself I use this class (which is also registered in the ConfigureServices method):
public class SimpleService : ScopedBackgroundService
{
private ISimpleBusiness simpleBusiness;
public SimpleService(IServiceScopeFactory serviceScopeFactory) : base(serviceScopeFactory)
{
}
public override async Task ProcessInScope(IServiceProvider serviceProvider, CancellationToken cancellationToken)
{
this.simpleBusiness = serviceProvider.GetService<ISimpleBusiness>();
foreach (var b in simpleBusiness.GetAll())
{
await this.simpleBusiness.Check(b);
}
}
}
This works good. But I have the problem that after each request the used memory increased. The garbage collector also doesnt get triggered. After a while and under certain circumstances I cant detect/find the memory increases rapidly in about 20 ms by up to 150 MB.
The SimpleBusiness class (implementing the interface ISimpleBusiness) uses a db context in simpleDA obtained via constructor injection:
public class SimpleBusiness : ISimpleBusiness
{
private ISimpleDA simpleDA;
private IHostingEnvironment hostingEnvironment;
...
public SimpleBusiness(ISimpleDA simpleDA, IHostingEnvironment environment, ...)
{
this.simpleDA = simpleDA;
this.hostingEnvironment = environment;
...
}
...
I guess this dbcontext and its attached objects dont get disposed/removed from memory. How can I pass the db context in a request-lifetime scope to the constructor when calling ProcessInScope in ScopedBackgroundService for the following created instances of all objects used in the underlying methods without changing the current data access and business classes/interfaces?
EDIT:
This is the memory and cpu usage over about 26 minutes.
The usage of about 26 minutes runtime

How to use IoC container (ex: NInject) in this particular context

I'm creating a background task controller as following:
public class TaskController
{
private TaskBase task;
public TaskController(ITask task)
{
this.task = task;
}
public void DoSomething()
{
task.DoSomething();
}
}
ITask interface:
interface ITask
{
void DoSomething();
}
TaskBase abtract class:
public abtract class TaskBase : ITask
{
\\some common fields/properties/methods
public void DoSomething()
{
\\perform action here
}
}
Task implementation:
public class Task1 : TaskBase
{
public Task1(string arg, int arg1)
{
}
}
public class Task2 : TaskBase
{
public Task2(bool arg, double arg)
{
}
}
This is an example on how to use it:
public void DoTask(string arg, int arg1)
{
Task1 task = new Task1(arg, arg1);
TaskController controller = new TaskController(task);
controller.DoSomething();
}
As you can see, I'm using manual injection in this approach. Now I want to switch to using IoC like NInject but after done some research, there's 2 things still bug me.
1. How can I tell the binding which concrete task to use in particular context?
2. How to pass dynamic arguments (`arg` and `arg1` on above example) to `Bind<T>` method
Note:
Please leave some comment if you see my question deserve a downvote in order to help me avoid making mistake in the future
The problems you have are caused by your design. If you change your design, the problems will go away. There are a few things you should do:
Separate data and behavior; currently, your Tasks contain a DoSomething method, while they also contain the data they need to execute.
And related, inject runtime data into your components' constructors.
If you extract the data from the behavior, you'll get the following:
// Definition of the data of Task1
public class Task1Data
{
public string Arg;
public int Arg1;
}
// The behavior of Task1
public class Task1 : ITask<Task1Data> {
public void Handle(TTask1Data data) {
// here the behavior of this task.
}
}
Here every task implements the generic ITask<TTaskData> interface:
public interface ITask<TTaskData>
{
Handle(TTaskData data);
}
With this design in place, we can now use it as follows:
private ITask<Task1Data> task1;
public Consumer(ITask<Task1Data> task1) {
this.task1 = task1;
}
public void DoTask(string arg, int arg1)
{
task1.Handle(new Task1Data { Arg = arg, Arg1 = arg1 });
}
And we register our tasks as follows:
kernel.Bind<ITask<Task1Data>>().To<Task1>();
kernel.Bind<ITask<Task2Data>>().To<Task2>();
kernel.Bind<ITask<Task3Data>>().To<Task3>();
Although I'm not very experienced with Ninject, I'm sure there's a way to transform these registrations to a convenient single line.
This design has many advantages. For instance, it makes adding cross-cutting concerns much easier. For instance, you can create a generic decorator that wraps each task in a transaction as follows:
public class TransactionTaskDecorator<T> : ITask<T> {
private readonly ITask<T> decoratee;
public TransactionTaskDecorator(ITask<T> decoratee) {
this.decoratee = decoratee;
}
public void Handle(T data) {
using (var scope = new TransactionScope()) {
this.decoratee.Handle(data);
scope.Complete();
}
}
}
Such decorator can be applied without the consumer having to know anything about it, since it just depends on the ITask<T> interface.
You can also add a decorator that allows executing the tasks in a background thread:
public class BackgroundTaskDecorator<T> : ITask<T> {
private readonly Func<ITask<T>> decorateeFactory;
private readonly ILogger logger;
public TransactionTaskDecorator(Func<ITask<T>> decorateeFactory, ILogger logger) {
this.decorateeFactory = decorateeFactory;
this.logger = logger;
}
public void Handle(T data) {
Task.Factory.StartNew(() =>
{
try {
// We're running on a different thread, so we must create the task here.
var decoratee = this.decorateeFactory.Invoke();
decoratee.Handle(data);
} catch (Exception ex) {
this.logger.Log(ex);
}
}
}
}
You can learn more about this design here.
1) Use Named properties like so
public TaskController([Named("MyName")] ITask task)
Then in the NinjectModule
Bind<ITask>().To<Task1>().Named("MyName");
2) Think you can use the same method as above
https://github.com/ninject/ninject/wiki/Contextual-Binding

Categories