如何模拟委托动作输入参数

时间:2012-08-07 14:48:00

标签: asp.net-mvc-3 unit-testing lambda moq anonymous-function

我正在尝试在下面的(配对)单元测试样本中安排传递给ICallback#Regsiter<T>(Action<T>)的lambda的输入参数(参见单元测试样本中的注释)。我试图避免将lambda抽象出来,因为它非常特殊和小,但我不确定这是否可行。

// IBus interface peek
public interface IBus {
    ICallback Send(IMessage message);
}

// ICallback interface peek
public interface ICallback {
    void Register<T>(Action<T> callback);
}

public enum ReturnCode { Success }

// Controller
public class FooController : AsyncController {
    readonly IBus _bus;
    //...
    // Action being unit tested
    public void BarAsync() {
        _bus
            .Send(ZapMessageFactory.Create())
            .Register<ReturnCode>(x => {
                AsyncManger.Parameters["returnCode"] = x;
            });
    }

    public ActionResult BarCompleted(ReturnCode returnCode) {
        // ...
    }
}

// Controller action unit test
[TestClass]
public class FooControllerTest {
    [TestMethod}
    public void BarTestCanSetAsyncManagerParameterErrorCodeToSuccess() {
        var fooController = ControllerUTFactory.CreateFooController();
        // HOW DO I MOCK THE ACTION DELEGATE PARAMETER TO BE ReturnCode.Success
        // SO I CAN DO THE ASSERT BELOW???
        fooController.BarAsync();
        Assert.AreEqual(ReturnCode.Success, (ReturnCode)fooController.AsyncManager.Parameters["returnCode"]);
    }
}

1 个答案:

答案 0 :(得分:0)

使用Mock<T>#Callback()就是答案:

[TestMethod}
public void BarTestCanSetAsyncManagerParameterErrorCodeToSuccess() {
    var mockCallback = new Mock<ICallback>();
    mockCallback
            .Setup(x => x.Register(It.IsAny<ReasonCode>())
            // THIS LINE IS THE ANSWER
            .Callback(action => action(ReasonCode.Success));
    var mockBus = new Mock<IBus>();
    mockBus
            .Setup(x => x.Send(It.IsAny<ZapMessage>())
            .Returns(mockCallback.Object);

    var fooController = new FooController(mockBus.Object);

    fooController.BarAsync();
    Assert.AreEqual(ReturnCode.Success, (ReturnCode)fooController.AsyncManager.Parameters["returnCode"]);
}