I am using Moq.Sequences and I am having trouble with testing async methods.
When I do this:
[Test]
public async Task Demo()
{
using (Sequence.Create())
{
_fooMock.Setup(f => f.Fooxiate()).InSequence();
_barMock.Setup(b => b.Baronize()).InSequence();
var result = await _cut.DoMyStuffAsync();
Assert.AreEqual("someString", result);
}
}
The I get an exception in the production code when calling _foo.Fooxiate() saying:
Moq.Sequences.SequenceUsageException: 'Mock invocation can only be called with an active MockSequence created with MockSequence.Create()
Am I doing something wrong or is testing of call sequence in async methods not supported?
Here is the full demo code including the above mentioned production code:
using System.Threading.Tasks;
using Moq;
using Moq.Sequences;
using NUnit.Framework;
namespace TestingAsync.Tests
{
[TestFixture]
public class SomeClassTests
{
private SomeClass _cut;
private Mock<IFoo> _fooMock;
private Mock<IBar> _barMock;
[SetUp]
public void Setup()
{
_fooMock = new Mock<IFoo>();
_barMock = new Mock<IBar>();
_cut = new SomeClass(_fooMock.Object, _barMock.Object);
}
[Test]
public async Task Demo()
{
using (Sequence.Create())
{
_fooMock.Setup(f => f.Fooxiate()).InSequence();
_barMock.Setup(b => b.Baronize()).InSequence();
var result = await _cut.DoMyStuffAsync();
Assert.AreEqual("someString", result);
}
}
}
public class SomeClass
{
private readonly IFoo _foo;
private readonly IBar _bar;
public SomeClass(IFoo foo, IBar bar)
{
_bar = bar;
_foo = foo;
}
public async Task<string> DoMyStuffAsync()
{
return await Task.Run(() => DoMyStuff());
}
private string DoMyStuff()
{
_foo.Fooxiate();
_bar.Baronize();
return "someString";
}
}
public interface IBar
{
void Baronize();
}
public interface IFoo
{
void Fooxiate();
}
}
This other answer explains correctly how Moq.Sequences doesn't didn't properly support async / await due to its use of [ThreadStatic].
Based on the OP's request, I've updated that library to provide better support for modern concurrent programming patterns. (Hopefully, people are programming with Tasks these days, not Threads.)
Starting with version 2.1.0, you can make Moq.Sequences track the ambient sequence using a AsyncLocal<Sequence> instead of a [ThreadStatic] variable. This means that the ambient sequence can "flow" across async boundaries such as an await and still be visible in the continuation (which might run on a different thread).
For reasons of backwards compatibility, you currently need to opt in to the new behavior by doing the following before any of your tests run:
Sequence.ContextMode = SequenceContextMode.Async;
At this time of writing, the new behavior hasn't been extensively tested so issue and bug reports are welcome.
Moq.Sequences is not written to be multi-threaded as it uses the [ThreadStatic] attribute to keep track of the ambient Sequence.
[ThreadStatic]
private static Sequence instance;
The result is that the ambient Sequence is only stored for the current thread. Then you call Task.Run which spawns a background thread to do work. This results in the exception being thrown because instance is null for that thread.
if (Instance == null)
throw new SequenceUsageException(context + " can only be called with an active MockSequence created with MockSequence.Create()");
https://github.com/dwhelan/Moq-Sequences → src/Moq.Sequences/Sequence.cs
There is not a good way for Moq.Sequences to be able to guarantee order of calls in async code because:
Concurrent code does not typically have deterministic order of execution.
Async is an abstraction over threads and because of that is even less predictable than threads. There are many techniques that result in non-deterministic sequence of calls, such as doing work in background threads with Task.Run, using Parallel.For/ForEach, using TPL dataflow, using Task.WhenAll, etc.
Related
I am trying to lock a section of my code that is synchronous and release the lock in an asynchronous code block (after an execution of a task). I have read about 'AutoResetEvent', and wanted to implement its signaling functionality between the caller and the callee of the code implementation.
The aim is to lock the code that is responsible for verifying whether the transaction was administered before. After the check is done and the transaction was saved, I release the code. The check and saving operations are asynchronous, and the lock release happens at 'continueWith' delegate function.
I have the following abstraction and implementation of AutoResetEvent:
public interface IThreadLockKeyProvider { public AutoResetEvent PayLock { get; } }
public class ThreadLockKeyProvider : IThreadLockKeyProvider
{
public static readonly AutoResetEvent _payLock;
static ThreadLockKeyProvider()
{
_payLock = new AutoResetEvent(true);
}
public AutoResetEvent PayLock { get { return _payLock; } }
}
The instance is injected as a singleton in .net core dependency injection container.
The code of the eventhandler method is the following:
public Task<Unit> Handle(ProcessPaymentCommand command, CancellationToken cancellationToken)
{
_threadLockKeyProvider.PayLock.WaitOne();
var res = _brandDepositStrategy.AdministerDeposit().Result;
return Task.FromResult(Unit.Value);
}
The AdministerDeposit method that releases the lock.
public override async Task<Task> AdministerDeposit()
{
Task<PaymentTransactions> dbOperation = _transactionAdministrationFacade.UpdateDbTransactionAsync(_IPNRequestDto);
return await dbOperation.ContinueWith(async x =>
{
_threadLockKeyProvider.PayLock.Set();
if (x.IsFaulted)
throw x.Exception;
_transactionAdministrationFacade.CallBackDto = await _responseComposer.GetPaymentResponseDto(x.Result, _IPNRequestDto);
await CreateDepositSF();
});
}
The question is whether the implementation cause any problems?
Note: The code does work. It doesnt crash and pass the unit tests that I built.
in theory there's nothing wrong with AutoResetEvent in this scenario, but: it isn't exactly built for async, which means that your WaitOne() blocks a thread - exactly what you're trying to avoid. Likewise, you're using sync-over-async. Since this is basically an async lock, seeing the entry/exit so far apart concerns me - it makes it very easy to introduce errors.
Let's try and fix those things:
use SemaphoreSlim as an async-friendly lock
await our result
move the entry/exit of the lock into the same place
example:
private readonly SemaphoreSlim _lock = new(1, 1);
public async Task<int> SomeOuterMethodAsync(CancellationToken cancellationToken)
{
await _lock.WaitAsync(cancellationToken);
try
{
var s = await SomeInnerMethodAsync(cancellationToken);
return s.Length; // just some projection
}
finally
{
_lock.Release();
}
}
// note: this could be in unrelated types/instances/etc
private Task<string> SomeInnerMethodAsync(CancellationToken cancellationToken)
=> throw new InvalidOperationException("not shown");
This is the code I'm trying to test for a racing condition,
I have a legacy code which I can change to a certain extent.
Inside my main function, I have a function which returns a Task that we await and another function for UI that must not be blocked because it runs on a different thread.
In the original code we do not care about the result we are just initializing some classes, and I test that the ViewModel is not null.
In the example code I gave here, I changed the code to exemplify the problem of the race condition.
Currently, my test will fail. How do I properly test my racing condition?
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Myclass tempClass = new Myclass();
tempClass.CreateImage();
Assert.AreEqual(3, tempClass.Sum);
}
}
public class Myclass
{
public int Sum;
public Myclass()
{
Sum = 0;
}
public async Task CreateImage()
{
await InternalFunction();
await Task.Run(() => Physics());
}
public async Task InternalFunction()
{
await Task.Run(() =>
{
Math();
});
}
public void Math()
{
Sum += 1;
}
public void Physics()
{
Sum += 2;
}
}
If I run the test, the sum property will be 1, and not 3 as expected. How do I change the code to be able to perform all of the flow of CreateImage() function and only once all of the threads are done, I want to assert the result/content of TempClass.
You will have to await the code in the test itself as well, otherwise the Aseert will take place before the code has completed:
[TestMethod]
public async Task TestMethod1()
{
Myclass tempClass = new Myclass();
await tempClass.CreateImage();
Assert.AreEqual(3, tempClass.Sum);
}
But to me this code has some pifalls. There is a lot of wrapping synchronous code in Task.Run which won't give any benefits as it is right now. Also Sum is not threadsafe so if at any point in time it will be accessed by threads concurrent bad things can happen.
The CreateImage method is async, however your unit test method isn't, so your test may complete before CreateImage is finished.
You didn't specify which version of NUnit you're using, but the following works in the latest version of NUnit 3
[TestFixture]
public class UnitTest1
{
[Test]
public async Task TestMethod1()
{
Myclass tempClass = new Myclass();
await tempClass.CreateImage();
Assert.AreEqual(3, tempClass.Sum);
}
}
Of course, This assumes that MyClass is thread-safe - If your real code uses multiple threads concurrently modifying the state of a MyClass instance, then you may also need to consider using a synchronisation mechanism such as one of those built into the BCL - https://learn.microsoft.com/en-us/dotnet/standard/threading/synchronizing-data-for-multithreading
Also, you might consider using some of the async-friendly helpers developed by Stephen Cleary - https://github.com/StephenCleary/AsyncEx
I have a situation where I have an object tree created by a special factory. This is somewhat similar to a DI container, but not quite.
Creation of objects always happens via constructor, and the objects are immutable.
Some parts of the object tree may not be needed in a given execution and should be created lazily. So the constructor argument should be something that is just a factory for on-demand creation. This looks like a job for Lazy.
However, object creation may need to access slow resources and is thus always async. (The object factory's creation function returns a Task.) This means that the creation function for the Lazy would need to be async, and thus the injected type needs to be Lazy<Task<Foo>>.
But I'd rather not have the double wrapping. I wonder if it is possible to force a Task to be lazy, i.e. to create a Task that is guaranteed to not execute until it is awaited. As I understand it, a Task.Run or Task.Factory.StartNew may start executing at any time (e.g. if a thread from the pool is idle), even if nothing is waiting for it.
public class SomePart
{
// Factory should create OtherPart immediately, but SlowPart
// creation should not run until and unless someone actually
// awaits the task.
public SomePart(OtherPart eagerPart, Task<SlowPart> lazyPart)
{
EagerPart = eagerPart;
LazyPart = lazyPart;
}
public OtherPart EagerPart {get;}
public Task<SlowPart> LazyPart {get;}
}
I'm not sure exactly why you want to avoid using Lazy<Task<>>,, but if it's just for keeping the API easier to use, as this is a property, you could do it with a backing field:
public class SomePart
{
private readonly Lazy<Task<SlowPart>> _lazyPart;
public SomePart(OtherPart eagerPart, Func<Task<SlowPart>> lazyPartFactory)
{
_lazyPart = new Lazy<Task<SlowPart>>(lazyPartFactory);
EagerPart = eagerPart;
}
OtherPart EagerPart { get; }
Task<SlowPart> LazyPart => _lazyPart.Value;
}
That way, the usage is as if it were just a task, but the initialisation is lazy and will only incur the work if needed.
#Max' answer is good but I'd like to add the version which is built on top of Stephen Toub' article mentioned in comments:
public class SomePart: Lazy<Task<SlowPart>>
{
public SomePart(OtherPart eagerPart, Func<Task<SlowPart>> lazyPartFactory)
: base(() => Task.Run(lazyPartFactory))
{
EagerPart = eagerPart;
}
public OtherPart EagerPart { get; }
public TaskAwaiter<SlowPart> GetAwaiter() => Value.GetAwaiter();
}
SomePart's explicitly inherited from Lazy<Task<>> so it's clear that it's lazy and asyncronous.
Calling base constructor wraps lazyPartFactory to Task.Run to avoid long block if that factory needs some cpu-heavy work before real async part. If it's not your case, just change it to base(lazyPartFactory)
SlowPart is accessible through TaskAwaiter. So SomePart' public interface is:
var eagerValue = somePart.EagerPart;
var slowValue = await somePart;
Declaration:
private Lazy<Task<ServerResult>> _lazyServerResult;`
ctor()
{
_lazyServerResult = new Lazy<Task<ServerResult>>(async () => await
GetServerResultAsync())
}
Usage:
ServerResult result = await _lazyServerResult.Value;
Using the constructor for Task make the task lazy a.k.a not running until you say it to run, so you could do something like this:
public class TestLazyTask
{
private Task<int> lazyPart;
public TestLazyTask(Task<int> lazyPart)
{
this.lazyPart = lazyPart;
}
public Task<int> LazyPart
{
get
{
// You have to start it manually at some point, this is the naive way to do it
this.lazyPart.Start();
return this.lazyPart;
}
}
}
public static async void Test()
{
Trace.TraceInformation("Creating task");
var lazyTask = new Task<int>(() =>
{
Trace.TraceInformation("Task run");
return 0;
});
var taskWrapper = new TestLazyTask(lazyTask);
Trace.TraceInformation("Calling await on task");
await taskWrapper.LazyPart;
}
Result:
SandBox.exe Information: 0 : Creating task
SandBox.exe Information: 0 : Calling await on task
SandBox.exe Information: 0 : Task run
However I strongly recommend you to use Rx.NET and IObservable as in your case you will get way less troubles for handling less naive cases to start your task at the right moment.
Also it makes the code a bit cleaner in my opinion
public class TestLazyObservable
{
public TestLazyObservable(IObservable<int> lazyPart)
{
this.LazyPart = lazyPart;
}
public IObservable<int> LazyPart { get; }
}
public static async void TestObservable()
{
Trace.TraceInformation("Creating observable");
// From async to demonstrate the Task compatibility of observables
var lazyTask = Observable.FromAsync(() => Task.Run(() =>
{
Trace.TraceInformation("Observable run");
return 0;
}));
var taskWrapper = new TestLazyObservable(lazyTask);
Trace.TraceInformation("Calling await on observable");
await taskWrapper.LazyPart;
}
Result:
SandBox.exe Information: 0 : Creating observable
SandBox.exe Information: 0 : Calling await on observable
SandBox.exe Information: 0 : Observable run
To be more clear: The Observable here handle when to start the task, it is Lazy by default and will run the task everytime it is subscribed (here subscribe is used by the awaiter that enable the use of the await keyword).
You could, if you need to, make the task run only once every minute (or ever) and having its result published across all subscribers to save performance for instance, like in a real world app, all of this and many more is handled by observables.
I have a threading module in my app which manages initiating parallel operations. It adds various bits of timing and logging for reasons, and is complicated enough that I recently discovered I'd coded in a bug whereby it was initiating some of the tasks on doubly nested threads.
i.e. it was calling the equivalent of:
Task.Run(
async () => await Task.Run(
() => DoStuff();
);
).Wait()
Now on the one hand, that code works ... the target code gets run, and the waiting code doesn't continue until the target code has completed.
On the other hand, it's using 2 threads to do this rather than 1 and since we're having issues with thread-starvation, that's something of an issue.
I know how to fix the code, but I'd like to write a unit test to ensure that A) I've fixed all the bugs like this / fixed it in all the scenarios.
and B) no-one recreates this bug in the future.
But I can't see how to get hold of "all the threads that I've created". CurrentProcess.Threads gives me LOADS of threads, and no obvious way to identify which ones are the ones I care about.
Any thoughts?
As is often the solution with unit testing something that involves a static method (Task.Run in this case), you will likely need to pass something in as a dependency to your class that wraps this up and that you can then add behaviour to in the tests.
As #Rich suggests in his answer, you could do this by passing in a TaskScheduler. Your test version of this can then maintain a count of the tasks as they are enqueued.
Making a test TaskScheduler is actually a little ugly because of protection levels, but at the bottom of this post I have included one that wraps an existing TaskScheduler (e.g. you could use TaskScheduler.Default).
Unfortunately, you would also need to change your calls like
Task.Run(() => DoSomething);
to something like
Task.Factory.StartNew(
() => DoSomething(),
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
myTaskScheduler);
which is basically what Task.Run does under the hood, except with the TaskScheduler.Default. You could of course wrap that up in a helper method somewhere.
Alternatively, if you are not squeamish about some riskier reflection in your test code you could hijack the TaskScheduler.Default property, so that you can still just use Task.Run:
var defaultSchedulerField = typeof(TaskScheduler).GetField("s_defaultTaskScheduler", BindingFlags.Static | BindingFlags.NonPublic);
var scheduler = new TestTaskScheduler(TaskScheduler.Default);
defaultSchedulerField.SetValue(null, scheduler);
(Private field name is from TaskScheduler.cs line 285.)
So for example, this test would pass using my TestTaskScheduler below and the reflection trick:
[Test]
public void Can_count_tasks()
{
// Given
var originalScheduler = TaskScheduler.Default;
var defaultSchedulerField = typeof(TaskScheduler).GetField("s_defaultTaskScheduler", BindingFlags.Static | BindingFlags.NonPublic);
var testScheduler = new TestTaskScheduler(originalScheduler);
defaultSchedulerField.SetValue(null, testScheduler);
// When
Task.Run(() => {});
Task.Run(() => {});
Task.Run(() => {});
// Then
testScheduler.TaskCount.Should().Be(3);
// Clean up
defaultSchedulerField.SetValue(null, originalScheduler);
}
Here is the test task scheduler:
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
public class TestTaskScheduler : TaskScheduler
{
private static readonly MethodInfo queueTask = GetProtectedMethodInfo("QueueTask");
private static readonly MethodInfo tryExecuteTaskInline = GetProtectedMethodInfo("TryExecuteTaskInline");
private static readonly MethodInfo getScheduledTasks = GetProtectedMethodInfo("GetScheduledTasks");
private readonly TaskScheduler taskScheduler;
public TestTaskScheduler(TaskScheduler taskScheduler)
{
this.taskScheduler = taskScheduler;
}
public int TaskCount { get; private set; }
protected override void QueueTask(Task task)
{
TaskCount++;
CallProtectedMethod(queueTask, task);
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return (bool)CallProtectedMethod(tryExecuteTaskInline, task, taskWasPreviouslyQueued);
}
protected override IEnumerable<Task> GetScheduledTasks()
{
return (IEnumerable<Task>)CallProtectedMethod(getScheduledTasks);
}
private object CallProtectedMethod(MethodInfo methodInfo, params object[] args)
{
return methodInfo.Invoke(taskScheduler, args);
}
private static MethodInfo GetProtectedMethodInfo(string methodName)
{
return typeof(TaskScheduler).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
}
}
or tidied up using RelflectionMagic as suggested by #hgcummings in the comments:
var scheduler = new TestTaskScheduler(TaskScheduler.Default);
typeof(TaskScheduler).AsDynamicType().s_defaultTaskScheduler = scheduler;
using System.Collections.Generic;
using System.Threading.Tasks;
using ReflectionMagic;
public class TestTaskScheduler : TaskScheduler
{
private readonly dynamic taskScheduler;
public TestTaskScheduler(TaskScheduler taskScheduler)
{
this.taskScheduler = taskScheduler.AsDynamic();
}
public int TaskCount { get; private set; }
protected override void QueueTask(Task task)
{
TaskCount++;
taskScheduler.QueueTask(task);
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return taskScheduler.TryExecuteTaskInline(task, taskWasPreviouslyQueued);
}
protected override IEnumerable<Task> GetScheduledTasks()
{
return taskScheduler.GetScheduledTasks();
}
}
how to get hold of "all the threads that I've created"
Task.Run does not create any threads; it schedules jobs to run on the currently configured thread pool. See https://msdn.microsoft.com/library/system.threading.tasks.taskscheduler.aspx
If you mean "how to count the number of Tasks I've enqueued", I think you will need to create a custom implementation of TaskScheduler which counts incoming tasks and configure your test code to use it. There is an example of a custom TaskScheduler shown on the page linked above.
The thread class does have a Name property you could use to help identify all the threads you have created. Meaning a simple linq or for loop that will enable you to track which threads are yours.
https://msdn.microsoft.com/en-us/library/system.threading.thread.name(v=vs.110).aspx
Suppose I have a service which will be doing a long, expensive synchronous operation, i.e.
class ExclamationMarkService
{
public string GetData(string param)
{
Thread.Sleep(5000);
return param + "!";
}
}
To wrap it to become asynchronous via the EAP pattern I can do this:
class ExclamationMarkServiceEAP
{
public delegate void GetDataHandler(string data);
public event GetDataHandler GetDataCompleted;
public void GetDataWorker(object param)
{
var service = new ExclamationMarkService();
string data = service.GetData((string)param);
if (GetDataCompleted != null)
{
GetDataCompleted(data);
}
}
public void GetData(string param)
{
var thread = new Thread(GetDataWorker) {IsBackground = true};
thread.Start(param);
}
}
A similar thing with the new async/await operators can be done this way:
class ExclamationMarkServiceTaskAsync
{
public async Task<string> GetDataAsync(string param)
{
var service = new ExclamationMarkService();
return await Task.Run(() => service.GetData(param));
}
}
Usage:
public static void CallExclamationMarkServiceEAP()
{
var service = new ExclamationMarkServiceEAP();
service.GetDataCompleted += service_GetDataCompleted;
service.GetData("hello EAP");
}
static void service_GetDataCompleted(string data)
{
Console.WriteLine(data);
}
public static async void CallExclamationMarkServiceTaskAsync()
{
var service = new ExclamationMarkServiceTaskAsync();
var data = await service.GetDataAsync("hello TaskAsync");
Console.WriteLine(data);
}
static void Main(string[] args)
{
CallExclamationMarkServiceEAP();
CallExclamationMarkServiceTaskAsync();
Console.Read();
}
In both cases I managed to offload the work to the background. In the case of EAP, by explicitly starting a thread. For the async/await version, by using Task.Run.
Questions:
How would an APM implementation of my ExclamationMarkService look like?
Given both EAP and APM versions, how can they be wrapped by using existing methods of the Task class (Task.Factory.StartNew / Task.Factory.FromAsync, etc.) so that they could be used with the async/await keywords.
Long running synchronous operations that are not IO bound do not belong in the ThreadPool. Running such operations in the ThreadPool exposes you to the risk of starvation, where the pool does not spin up threads fast enough to be responsive to the needs of the many other APIs that rely on it.
If you want to run something long-winded, run it on your own thread, being careful to marshall the result back to the right context if it needs to show in some UI.
As such your first approach seems more appropriate.
On the other hand, TPL offers the opportunity to hint that the task is long running, and allows the system to decide the best place to run it. It's as simple as:
Task.Factory.StartNew(someSyncAction, TaskCreationOptions.LongRunning)
StartNew returns a Task. You can await it.