Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested asynchronous functions are not executed #300

Closed
tahirahmed76 opened this issue Nov 22, 2016 · 1 comment
Closed

Nested asynchronous functions are not executed #300

tahirahmed76 opened this issue Nov 22, 2016 · 1 comment

Comments

@tahirahmed76
Copy link

tahirahmed76 commented Nov 22, 2016

While mocking an object that have a synchronous method which internally executes an asynchronous method is not returning correct results. Eventhough, the setup was configured correctly, it didn't execute the nested asynchronous methods that returns a Task. Following is my object to mock.

public class ServiceClient
{
    private readonly Uri baseUri;

    public ServiceClient(string baseUri)
    {
        this.baseUri = new Uri(baseUri);
    }

    public void Process()
    {
        Console.WriteLine("Process has been started");

        DoSomething();

        // this is not working as well..
        // DoSomething().Wait();

        Console.WriteLine("Process has been completed");
    }

    public virtual Task DoSomething()
    {
        Console.WriteLine("DoSomething has been started");
        return DoSomethingMore();
    }

    public virtual Task DoSomethingMore()
    {
        Console.WriteLine("DoSomethingMore has been started");
        return Task.CompletedTask;
    }
}

And following is my unit test.

public void TestMethod1()
{
    var client = new Mock<MoqTesting.ServiceClient>(@''http://localhost:9000/service'');
    client.Setup(s => s.DoSomethingMore()).Returns(Task.CompletedTask);
    client.Object.Process();
    client.Verify(f => f.DoSomethingMore(), Times.Once);
}

This test fails and verify confirms that DoSomethingMore() method was never executed.
Complete source code is also attached to easily reproduce the issue.
MoqTesting.zip

@stakx
Copy link
Contributor

stakx commented Jun 25, 2017

The problem here is that Moq also mocks the DoSomething method. Because you haven't provided a setup for DoSomething, it will just return the default empty value for Task, which is a completed task. Your logic in DoSomething will never run.

You can get Moq to call your logic in DoSomething by setting client.CallBase to true:

var client = new Mock<ServiceClient>() { CallBase = true };
//                                      ^^^^^^^^^^^^^^^^^^^

@stakx stakx closed this as completed Jun 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants