【发布时间】:2014-12-17 23:39:27
【问题描述】:
作为测试的结果,我如何测试是否使用正确的参数调用了特定方法?我正在使用NUnit。
该方法不返回任何内容。它只是写在一个文件上。我正在为System.IO.File 使用模拟对象。所以我想测试该函数是否被调用。
【问题讨论】:
作为测试的结果,我如何测试是否使用正确的参数调用了特定方法?我正在使用NUnit。
该方法不返回任何内容。它只是写在一个文件上。我正在为System.IO.File 使用模拟对象。所以我想测试该函数是否被调用。
【问题讨论】:
需要更多上下文。所以我会放一个在这里添加最小起订量:
pubilc class Calc {
public int DoubleIt(string a) {
return ToInt(a)*2;
}
public virtual int ToInt(string s) {
return int.Parse(s);
}
}
// The test:
var mock = new Mock<Calc>();
string parameterPassed = null;
mock.Setup(c => x.ToInt(It.Is.Any<int>())).Returns(3).Callback(s => parameterPassed = s);
mock.Object.DoubleIt("3");
Assert.AreEqual("3", parameterPassed);
【讨论】:
Moq 制作动态代理以使其模拟不会生成新的 IL 指令,以使这成为可能...
您必须使用一些模拟框架,例如Typemock 或Rhino Mocks,或NMocks2。
NUnit 也有一个Nunit.Mock,但并不为人所知。
起订量的语法可以找到here:
var mock = new Mock<ILoveThisFramework>();
// WOW! No record/reply weirdness?! :)
mock.Setup(framework => framework.DownloadExists("2.0.0.0"))
.Returns(true)
.AtMostOnce();
// Hand mock.Object as a collaborator and exercise it,
// like calling methods on it...
ILoveThisFramework lovable = mock.Object;
bool download = lovable.DownloadExists("2.0.0.0");
// Verify that the given method was indeed called with the expected value
mock.Verify(framework => framework.DownloadExists("2.0.0.0"));
另外,请注意,您只能模拟 interface,因此如果您来自 System.IO.File 的对象没有接口,那么您可能无法做到。您必须将对 System.IO.File 的调用封装在您自己的自定义类中才能完成这项工作。
【讨论】:
通过对接口使用模拟。
假设您的类 ImplClass 使用接口 Finder,并且您希望确保使用参数“hello”调用 Search 函数;
所以我们有:
public interface Finder
{
public string Search(string arg);
}
和
public class ImplClass
{
public ImplClass(Finder finder)
{
...
}
public void doStuff();
}
然后你就可以为你的测试代码写一个mock了
private class FinderMock : Finder
{
public int numTimesCalled = 0;
string expected;
public FinderMock(string expected)
{
this.expected = expected;
}
public string Search(string arg)
{
numTimesCalled++;
Assert.AreEqual(expected, arg);
}
}
然后是测试代码:
FinderMock mock = new FinderMock("hello");
ImplClass impl = new ImplClass(mock);
impl.doStuff();
Assert.AreEqual(1, mock.numTimesCalled);
【讨论】:
在 Rhino Mocks 中,有一个名为 AssertWasCalled 的方法
这是一种使用方法
var mailDeliveryManager = MockRepository.GenerateMock<IMailDeliveryManager>();
var mailHandler = new PlannedSending.Business.Handlers.MailHandler(mailDeliveryManager);
mailHandler.NotifyPrinting(User, Info);
mailDeliveryManager.AssertWasCalled(x => x.SendMailMessage(null, null, null), o => o.IgnoreArguments());
【讨论】: