jeudi 30 juillet 2015

Verifying Mock method was called inside Task.Run

How can I verify that a method was called on a mock when the method itself is called in a delegate passed to Task.Run? By time mock.Verify is called the Task still hasn't executed.

I have tried await Task.Delay just before mock.Verify but this seems to leave the test runner hanging.

The reason for using Task.Run is to offload the logic to prevent an attacker from being able to differentiate whether the email address exists in the system by the time to execute.

using System.Threading.Tasks;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace AsyncTesting
{
    class MyController : Controller
    {
        public IEmailService EmailService { get; set; }

        public MyController(IEmailService emailService)
        {
            EmailService = emailService;
        }

        public ViewResult BeginPasswordReset(string emailAddress)
        {
            BeginPasswordResetAsync(emailAddress);

            return View();
        }

        private Task BeginPasswordResetAsync(string emailAddress)
        {
            return Task.Run(delegate
            {
                EmailService.Send(emailAddress);
            });
        }

    }

    internal interface IEmailService
    {
        void Send(string emailAddress);
    }

    internal class MyControllerTests
    {
        [TestMethod]
        public void BeginPasswordReset_SendsEmail()
        {
            var mockEmailService = new Mock<IEmailService>();
            var controller = new MyController(mockEmailService.Object);
            const string emailAddress = "email@domain.com";

            controller.BeginPasswordReset(emailAddress);

            mockEmailService.Verify(es=>es.Send(emailAddress));
        }
    }
}

Aucun commentaire:

Enregistrer un commentaire