02.09.2019
Posted by 

Not sure how to achieve this. I'm trying to unit test a method which waits a few minutes, see here:

  1. C++ Thread Sleep
  2. C Thread Sleep In Linux
  3. Unit Test Quizlet

This is my test method but I can't manage to mock the task delay stuff.

This is the error raised:

Thread sleep doesn’t lose any monitors or locks current thread has acquired. Any other thread can interrupt the current thread in sleep, in that case InterruptedException is thrown. How Thread Sleep Works. Thread.sleep interacts with the thread scheduler to put the current thread in wait state for specified period of time.

Moq.MockException : Expected invocation on the mock at least once, but was never performed: x => x.Publish(It.Is(y => y.Imei .imei)) No setups configured. No invocations performed. at Moq.Mock.ThrowVerifyException(MethodCall expected, IEnumerable1 setups, IEnumerable1 actualCalls, Expression expression, Times times, Int32 callCount) at Moq.Mock.VerifyCalls(Interceptor targetInterceptor, MethodCall expected, Expression expression, Times times) at Moq.Mock.Verify[T](Mock1 mock, Expression1 expression, Times times, String failMessage) at Moq.Mock1.Verify(Expression1 expression) at JustEat.PrivateAPN.Worker.UnitTests.TestRunners.JctRestartViaSmsAttemptTestFixture.RunJctTest_WhenRestartAttemptSmsIsSent_ShouldPublishJctRestartValidateMessageWithTheRightImei() in

I know I need to customize/configure my fixture in order to get into the callback but I'm not sure how to do it, any help would be very appreciated

  1. Process orientated - few, long running, heterogeneous tasks, often event based (waiting on notification), or polling (sleeping between cycles), often expressed using a thread or runnable. Testing either type of code can be hard; the work is done in another thread, and therefore notification of completion can be opaque, or is hidden behind a level of abstraction.
  2. Thread.Sleep(Interval); / Interval is passed in as a parameter to the class so I can just pass in 0 or 1 but I was interested as to how to mock the system clock if this wasn't the case. In my test I'd like to be able to simply set the time forward by TimeSpan Interval and have the thread wake up. I've never written tests for code.
Rober
RoberRober

3 Answers

You shouldn't be firing a Task off without awaiting for it to finish when your test and other things may rely on the result.

So I suggest you change to:

Another reason for awaiting is that you have this _queues if you intend to read from that later on, you can never guarantee the contents because there may still be a thread in the threadpool processing the Task.Delay.

Alternative

If you can't change the signature of the method then you will have to go with the Thread.Sleep() which will block the current thread until it has finished.

Because you did specify Task.Delay I would assume you are using it for the benefits of non blocking.

If you were to use Thread.Sleep() you may want to consider running the JctRestartViaSmsAttemptTestRunner in a Task.Run() so that is will only block the thread it is running on.

C unit test thread sleep chartC Unit Test Thread Sleep

Tests

If you have a method that does return Task<> then you will have to use .Result if you can't have async test method signatures. Which shouldn't be an issue if you run all your tests in serial. If you don't know why .Result and .Wait() are bad read here

So for your async version:

And your non async version stays the same.

Callum LiningtonCallum Linington
9,4349 gold badges51 silver badges110 bronze badges

I think the problem is the test is allowed to finish. Your creating a new task after the delay to start but the test function itself completes before this.

I am not overly familiar with the testing framework. But I would expect you want to use .Wait() on the end of the task. This will create a blocking task and your main test thread will be blocked until the delay is finished.

AnubisAnubis

The execute method is not realy testable, because it starts a delayed task, but you are not able to manage that task from outside.

So, you could try to work with Thread.Sleep which is not nice but should work:

JanDotNetJanDotNet

Not the answer you're looking for? Browse other questions tagged c#moqautofixture or ask your own question.

Disclaimer:

C++ Thread Sleep

This post is based on the C# 5.0 CTP. Everything described here is subject to future changes.

Last time I demonstrated that the synchronization context is also relevant for unit testing and that you might need to setup one in your tests. This time we’re going to explore what we can do when a asynchronous method returns void instead of a task.

Once again we write some code for our imaginary desktop application. This time we test a method which sends some stuff to costumers. When the package is sent an event is raised. First the synchronous version. It’s straight forward, we package the goods and then send it. When we’re done we fire the event.

The Implementation

The Test

As expected everything runs smooth. Now we’re turning the method into an asynchronous implementation

As soon as we try to update the test-method we’re facing a problem. We cannot wait for a void-result. This means there’s no way to wait for the completion of the task. Well the easiest thing to do is to change the result to return a task. This allows us to wait in the test.

Returning a Task

C Thread Sleep In Linux

The Test

In The Case Of Void

Now we’ve seen that when we return a task instead of void we can make our testing-life much easier. But what if that’s not possible? For example because we don’t want to break the API. Or if it’s a library call which we cannot change. Then this gets a little more tricky. When the method returns void we cannot wait for the task to complete. A ugly work around would be to just use Thread.Sleep for a certain time an hope that everything completes meanwhile. However this is a brittle method and prolongs our test unnecessary. What can we do instead? Remember the previous post where we used a special synchronization-context which allowed us to wait on a task? Well does this really have to be a task? I mean we can wait for other things, right?

So the basic idea is to extend our test synchronization context to provide a special wait-method. And while we’re waiting we process other messages. This is actually only a small extension to our existing code

Now we can use this in our test. We run our test-code in the test synchronization context. Then we wait until the condition is fulfilled and finally continue

You’ve probably noticed that this test will run forever instead of failing. Unfortunately we cannot fix that. The only thing we can do is to implement some kind of timeout and maybe use a reasonable default. But you can implement that without my help ;).

Unit Test Quizlet

Thread

Conclusion

In this post I demonstrated that you should always return a task in an asynchronous API instead of void. This allows us to easily test the code and makes it more flexible. In the cases where we have to deal with asynchronous code which doesn’t return a task we have to get creative with special wait conditions.

Now I’ve finished with my little tour through Unit testing with the new asynchronous features. This post series is by no means a complete guide. It’s here to get an impression where the difficulties lie. I think when the async feature ships some knowledge and patterns have already emerged. And maybe we all should take a looks at F#. Because F# has had asynchronous workflows for quite a while. And don’t forget do download and experiment with the Async CTP yourself.