使用在 Task.Run 内调用的 Moq 方法进行单元测试

用户2128702

我正在尝试在要测试的方法中模拟服务调用。

方法体如下所示:

public string OnActionException(HttpActionContext httpRequest, Exception ex)
{
    var formattedActionException = ActionLevelExceptionManager.GetActionExceptionMessage(httpRequest);

    var mainErrorMessage = $"[{formattedActionException.ErrorId}]{formattedActionException.ErrorMessage}, {ex.Message}";

    this.LogError(mainErrorMessage, ex);

    if (this._configuration.MailSupportOnException)
        Task.Run(async () => await this._mailService.SendEmailForThrownException(this._configuration.SupportEmail, $"{mainErrorMessage} ---> Stack trace: {ex.StackTrace.ToString()}")); 

    return $"(ErrID:{formattedActionException.ErrorId}) {formattedActionException.ErrorMessage} {formattedActionException.KindMessage}";
}

我试图在我的测试中模拟的是:

Task.Run(async () => await this._mailService.SendEmailForThrownException(this._configuration.SupportEmail, $"{mainErrorMessage} ---> Stack trace: {ex.StackTrace.ToString()}"));

测试方法如下所示:

[TestMethod]
public void We_Send_System_Exception_On_Email_If_Configured_In_Settings()
{
    // arrange
    this._configurationWrapperMock.Setup(cwm => cwm.MailSupportOnException)
        .Returns(true);
    this._mailServiceMock.Setup(msm => msm.SendEmailForThrownException(It.IsAny<string>(), It.IsAny<string>()))
        .Returns(Task.FromResult(0));

    // act
    var logger = new ApiLogger(this._configurationWrapperMock.Object, this._mailServiceMock.Object);
    logger.OnActionException(
        new HttpActionContext(
            new HttpControllerContext()
            {
                Request = new HttpRequestMessage()
                {
                    Method = HttpMethod.Get,
                    RequestUri = new System.Uri("https://www.google.bg/")
                }
            }, 
            new ReflectedHttpActionDescriptor() { }
        ), 
        new System.Exception());

    // assert
    this._mailServiceMock.Verify(
        msm => msm.SendEmailForThrownException(It.IsAny<string>(), It.IsAny<string>()), 
        Times.Once);
}

问题是该方法从未被调用,所以我的断言失败了。

编辑:我可以将我的问题更改为:我如何需要重新编写我的方法以使其可测试?

凯丽·布朗

我尝试了上面场景的一个简单的精简版本,并且单元测试始终通过。

public interface IService
{
    Task<bool> Do();
}

public class AsyncService : IService
{
    public async Task<bool> Do()
    {
        return await Task.FromResult(true);
    }
}

public class MyClass
{
    private IService service;

    public MyClass(IService service)
    {
        this.service = service;
    }

    public async Task<bool> Run()
    {
        return await this.service.Do();
    }
}

[TestMethod]
public async Task TestAsyncMethod()
{
    Mock<IService> mockService = new Mock<IService>();
    mockService.Setup(m => m.Do()).Returns(Task.FromResult(false));

    MyClass myClass = new MyClass(mockService.Object);
    await myClass.Run();

    mockService.Verify(m => m.Do(), Times.Once);
}

看起来您需要让 OnActionException 返回一个 Task<string> ,然后也使单元测试异步。因此,与其使用 Task.Run(),不如在 OnActionException 方法中返回 await this._mailService.SendEmailForThrownException()。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用在方法中具有依赖项的moq来对类进行单元测试?

使用 Moq 框架进行单元测试

使用Moq进行单元测试

使用Moq的单元测试cosmosDb方法

使用 Moq 和接口进行单元测试

使用Moq和xUnit对服务进行单元测试

如何使用Moq Azure Key Vault进行单元测试

使用Moq .net Core进行单元测试文件上传

在Xamarin中使用Moq进行NUnit单元测试

如何使用Entity Framework和Moq进行单元测试?

使用Moq进行WCF服务的单元测试

使用Moq和Autofac进行单元测试

对在Swift中使用REST调用的方法进行单元测试

使用Moq模拟单元测试的异步方法

单元测试-如何使用MOQ进行MOQ WCF客户端

使用 Moq 进行单元测试时出现错误“”表达式树可能不包含使用可选参数的调用或调用””

使用Moq安排单元测试

尝试对使用模拟 Task<TResult> 的方法进行单元测试时出现问题

如何调用在单元测试中注入参数的方法?

使用Moq对通用工作单元和存储库模式框架进行单元测试

使用Moq进行单元测试的工作单元和通用存储库模式框架

使用Moq验证方法调用

如何使用Moq对在.NET中使用asmx服务的应用程序进行单元测试

Moq Framework对返回任务的方法进行单元测试

使用Moq对MVC6中的控制器路由功能进行单元测试

使用MOQ嵌套类和接口C#进行单元测试

如何使用Moq对.NET Core 3.1中的LoggerMessage.Define()进行单元测试?

在使用Moq和AutoFixture进行单元测试API时模拟HttpResponseMessage

如何使用Moq对Service Stacks Redis Client进行单元测试