使用MoQ设置后台工作项

时间:2017-05-29 13:36:29

标签: c# unit-testing asp.net-web-api moq

我是单元测试的新手,我在单元测试后台工作时遇到了一些困难。

正在测试的方法

[HandleExceptions(LoggerName)]
public override IHttpActionResult ValidateToken(string auth_token)
{
    var response = new HttpResponseMessage();
    var userInfo = this._userInfoService.CreateUserInfoModel(auth_token);

    response.StatusCode = HttpStatusCode.BadRequest;

    if (userInfo.Status.IsSuccess)
    {
        //-- I want to test if the following worker is calling RunPlayerDetailsWorkflow method exactly once.
        _taskScheduler.QueueBackgroundWorkItem(task => 
            this._playerDetailsService.RunPlayerDetailsWorkflow(userInfo.UserID, userInfo.ServerID));

        response.StatusCode = HttpStatusCode.OK;
    }

    response.Content = new StringContent(_userInfoService.ParseUserInfo(userInfo));
    response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");

    return this.ResponseMessage(response);
 }

测试方法

[Test]
public void TestValidateToken_Should_Call_PlayerDetailsService_RunPlayerDetailsWorkflow_Exactly_Once()
{
    // Arrange
    var userInfoModel = AdminControllerHelpers.CreateUserInfoModel();
    userInfoModel.Status = ETIStatus.CreateSuccess();
    _mockUserInfoService
        .Setup(m => m.CreateUserInfoModel(It.IsAny<string>()))
        .Returns(userInfoModel);
    _mockUserInfoService
        .Setup(s => s.ParseUserInfo(userInfoModel))
        .Returns(_randomString);
    _mockPlayerService
        .Setup(m => m.RunPlayerDetailsWorkflow(userInfoModel.UserID, userInfoModel.ServerID));
    //-- this is where I got the error.
    _mockTaskScheduler
        .Setup(t => t.QueueBackgroundWorkItem(
            obj => _mockPlayerService.Object.RunPlayerDetailsWorkflow(userInfoModel.UserID,
                userInfoModel.ServerID)));

    // Act
    _controller.ValidateToken(It.IsAny<string>());

    // Assert
    _mockPlayerService
        .Verify(m => m.RunPlayerDetailsWorkflow(userInfoModel.UserID, userInfoModel.ServerID), Times.Exactly(1));
}

即使我正确设置了所有内容(至少对我而言),我也会收到以下错误:

  

System.Core.dll中发生了'System.ArgumentException'类型的异常,但未在用户代码中处理。其他信息:参数类型不匹配

我正在嘲笑的任务计划程序界面

public interface ITaskScheduler
{
    /// <summary>
    ///   Schedules a task which can run in the background, independent of any request.
    /// </summary>
    /// <param name="workItem"> A unit of execution.</param>
    void QueueBackgroundWorkItem(Action<CancellationToken> workItem);
}

1 个答案:

答案 0 :(得分:2)

更改设置以期待操作,然后使用回调执行模拟

_mockTaskScheduler
    .Setup(_ => _.QueueBackgroundWorkItem(It.IsAny<Action<CanellationToken>>()))
    .Callback((Action<CancellationToken> action) => action(CancellationToken.None));

在行使测试方法时,无需使用It.IsAny<>()。只需传递一个值。

// Act
_controller.ValidateToken(String.Empty);

// Assert
_mockPlayerService
    .Verify(m => m.RunPlayerDetailsWorkflow(userInfoModel.UserID, userInfoModel.ServerID), Times.Exactly(1));

应该能够按预期进行测试。