使用 MoQ 设置后台工作项

Setting up background work item using 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));
}

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

An exception of type 'System.ArgumentException' occurred in System.Core.dll but was not handled in user code. Additional information: Argument types do not match

我正在模拟的 Task Scheduler 界面

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);
}

更改设置以期待一个动作,然后使用回调来执行模拟

_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));

现在应该可以按照预期进行测试了