在 C# 中使用 Moq 测试回调

Testing a callback with Moq in C#

学习最小起订量,需要一些帮助来测试回调结果。结构是:我有一个 DateManager 对象,它依赖于对服务器进行异步调用的 DateServer 对象。

DateServer.GetValidDate 将采用 yyyy-MM-dd 中的日期字符串,并将使用相同格式的字符串执行给定的回调。

如何设置模拟服务器才能通过下面的测试?一个简单的模拟设置是我的模拟 DateServer 将简单地 return 提供给它的任何字符串(在回调中)。

这是我的设置。我想我的大部分结构都是正确的,但需要帮助填写 ?????在下面的代码中。如果我应该更好地测试回调 return,那么我也对此很感兴趣。

public interface IDateServer
{
    // with a currencyPair (ie: USDCAD), verifies that the given date is 
    // valid for a potential transaction.  
    // Callback is used to process the returned result, which is a date string.
    void GetValidDate(string currencyPair, string date, Action<string> callback);
}

public interface IDateManager
{
    void GetDate(string currencyPair, string dateCode, Action<string> callback);
}

[TestClass]
public class DateManagerTests
{
    [TestMethod]
    public void GetDateTest()
    {
        ManualResetEvent ar = new ManualResetEvent(false);

        Mock<IDateServer> server = new Mock<IDateServer>();
        DateTime tradeDate = new DateTime(2016, 2, 17);

        server.Setup( ???? );

        IDateManager dm = new DateManager(tradeDate, server);

        string ret = "";
        dm.GetDate("USDCAD", "2016-02-17", (string s) =>
        {
            ret = s;
            ar.Set();
        });

        ar.WaitOne();

        Assert.AreEqual<string>(ret, "2016-02-17");

    }

}

这将为 GetValidDate 设置回调,并允许您访问在模拟接口上调用时传递给该方法的任何参数。

Mock<IDateServer> server = new Mock<IDateServer>();

const string testDateString = "2016-02-17";
const string testCurrencyPair = "USDCAD";

server.Setup(obj => obj.GetValidDate(It.IsAny<string>(), 
                                     It.IsAny<string>(), 
                                     It.IsAny<Action<string>>()))
      .Callback<string, string, Action<string>>((currencyPair, date, callback) =>
      {
            //  The parameters passed into GetValidDate (see below) 
            //  will be available in here.
            Debug.WriteLine(currencyPair);
            Debug.WriteLine(date);
      });

server.Object.GetValidDate(testCurrencyPair, testDateString, null);

根据我对 Callback 方法的理解,这只会通知您实际调用了模拟方法以及调用了哪些参数。

如果您想测试 DateManager,您需要确保 DateManager 调用 DateServer 依赖项的 GetValidDate 方法参数集。该方法没有 return 任何东西,因此不需要设置。

由于调用回调方法的DataServer不是被测试的class,所以回调是否真的被调用并不重要。您必须在 DateServer 的单独测试中对此进行测试。

因此,以下测试方法应验证 DateManager 将正确的参数传递给 DateServer(在这种情况下正确 = 传递给 DateManager 的参数) :

[TestMethod]
public void GetDateTest()
{
    Mock<IDateServer> server = new Mock<IDateServer>();
    Action<string> callback = (string s) => { };
    IDateManager dm = new DateManager(server.Object);
    dm.GetDate("USDCAD", "2016-02-17", callback);
    server.Verify(x => x.GetValidDate("USDCAD", "2016-02-17", callback));
}