0

I have a sample controller in an Asp.Net Core WebApi. The controller is for testing only and mocks an actual service call. Since the async method lacks an await, it will run synchronously.

I realize the following question will seem like an academic exercise. How would I mock this service call to simulate an asynchronous operation that simply returns false?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace Controllers
{
    [ApiController]
    [Route("Api/[controller]/[action]")]
    public class SomeController : ControllerBase
    {
        private readonly ILogger<SomeController> _logger;
        public SomeController(ILogger<SomeController> logger)
        {
            _logger = logger;
        }

        [HttpPost]
        public async Task<bool> SampleAction(string foobar)
        { 
            try
            {
                // Always return false for testing purposes, 
                return false;
            }
            catch (Exception e)
            {
                _logger.LogError("Failed to to process SampleAction", e);
                return false;
            }
        }
    }
}

The preceding code block results in the following compiler warning:

Warning CS1998 This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

JohnB
  • 2,895
  • 4
  • 34
  • 55

1 Answers1

4

Remove async, and use Task.FromResult to wrap a value in a task:

[HttpPost]
public Task<bool> SampleAction(string foobar)
{
    return Task.FromResult(false);
}

This returns an already completed task with the specified result (which means awaiting this task immediately gives you the result). Similar methods exist to create an already failed or already cancelled task.

Etienne de Martel
  • 30,360
  • 7
  • 86
  • 102