在 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));
}
学习最小起订量,需要一些帮助来测试回调结果。结构是:我有一个 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));
}