如何断言调用具体类上的私有方法(TypeMock/NMock/等..)?
我正在尝试为下面的类中的“IsUnique”函数编写一个单元测试,如下所示:
class Foo
{
public bool IsUnique(params...)
{
ValidateStuffExists(params);
return CheckUniqueness(params);
}
private void ValidateStuffExists(params)
{
//does some validation
}
private bool CheckUniqueness(params)
{
//does logic to determine if its unique per params
return result;
}
}
我想在这里测试的唯一事情是调用 ValidateStuffExists 和 CheckUniqueness 并传递参数。这就是这个函数所做的一切,所以这就是我要测试的全部(我将改变“仅测试公共行为”伪规则并在这里测试私有方法,因为它要么有一个大的复杂方法/测试,要么测试 2 个私有方法)方法)。
我对任何模拟库持开放态度。我使用 NMock 并且不认为它适合该任务 - 所以我下载了 TypeMock,因为我已经阅读并听说这是最好的,它甚至可以模拟具体的类/非接口方法调用...
我我在测试中做了类似的事情,它在“Isolate.WhenCalled”行抛出异常:
CrmEntityUniqueValidator_Accessor target = new CrmEntityUniqueValidator_Accessor(); // TODO: Initialize to an appropriate value
DynamicEntity entity = null; // TODO: Initialize to an appropriate value
string[] propertyNames = null; // TODO: Initialize to an appropriate value
bool tru = true;
Isolate.WhenCalled(() => target.CheckUniqueness(entity, propertyNames, null, null)).WillReturn(tru);
target.ValidatePropertiesExist(entity, propertyNames);
Isolate.Verify.WasCalledWithArguments(() => target.ValidatePropertiesExist(entity, propertyNames));
Isolate.Verify.WasCalledWithArguments(() => target.CheckUniqueness(entity, propertyNames, null, null));
这会抛出一个异常,如 “*** WhenCalled 不支持使用方法调用作为参数。”
即使我能够使用 CLR 类做同样的事情 - 我可以模拟 DateTime.Now 这样做(代码有效):
DateTime endOfWorld = new DateTime(2012, 12, 23);
Isolate.WhenCalled(() => DateTime.Now).WillReturn(endOfWorld);
DateTime dt = DateTime.Now;
Assert.AreEqual(dt, endOfWorld);
有人有任何建议吗?我是否必须将这两个方法分成一个单独的类并创建一个接口是唯一的方法?或者使我的方法/测试复杂化???我这里一定缺少一些东西...非常感谢您提前提供的任何帮助。
编辑:我想我正在尝试模拟类中的 2 个私有方法以进行一个单元测试。我怎样才能做到这一点,而不必将这两个方法拆分为单独的类/接口?
I am trying to write a unit test for the 'IsUnique' function in the class below that looks like this:
class Foo
{
public bool IsUnique(params...)
{
ValidateStuffExists(params);
return CheckUniqueness(params);
}
private void ValidateStuffExists(params)
{
//does some validation
}
private bool CheckUniqueness(params)
{
//does logic to determine if its unique per params
return result;
}
}
The only thing I want to test here is that ValidateStuffExists and CheckUniqueness is called and passed the arguments. That's all this function does so it's all I'm going to test (I'll bend the 'test public behavior only' psuedo-rule and test the private methods here, because its either have one big complicated method/tests or testing 2 private methods).
I am open to any mocking library. I use NMock and didn't think it was up for the Task - so I downloaded TypeMock as I've done reading and heard that this was the best and that it could mock out even concrete classes / non interface method calls...
I'm doing something like this in my test and it throws exception at the 'Isolate.WhenCalled' line:
CrmEntityUniqueValidator_Accessor target = new CrmEntityUniqueValidator_Accessor(); // TODO: Initialize to an appropriate value
DynamicEntity entity = null; // TODO: Initialize to an appropriate value
string[] propertyNames = null; // TODO: Initialize to an appropriate value
bool tru = true;
Isolate.WhenCalled(() => target.CheckUniqueness(entity, propertyNames, null, null)).WillReturn(tru);
target.ValidatePropertiesExist(entity, propertyNames);
Isolate.Verify.WasCalledWithArguments(() => target.ValidatePropertiesExist(entity, propertyNames));
Isolate.Verify.WasCalledWithArguments(() => target.CheckUniqueness(entity, propertyNames, null, null));
This throws an exception like "*** WhenCalled does not support using a method call as an argument."
Even though I'm able to do the same thing with a CLR class - I can mock out DateTime.Now doing this (code works):
DateTime endOfWorld = new DateTime(2012, 12, 23);
Isolate.WhenCalled(() => DateTime.Now).WillReturn(endOfWorld);
DateTime dt = DateTime.Now;
Assert.AreEqual(dt, endOfWorld);
Anyone have any advice here? Do I have to split these 2 methods into a seperate class and make an interface is the only way? or complicate my method/tests??? There must be something I'm missing here... Thanks much for any help in advance.
EDIT: I guess I'm trying to mock out the 2 private methods in the class for the one unit test. How could I do this without having to split out those 2 methods into a seperate class / interface?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
RhinoMocks 有
AssertWasCalled
方法可以用于保证一个方法调用另一个方法......但我不确定您是否可以在您正在单元测试的同一类的私有函数上执行此操作。我认为只有当您想要存根的两个方法位于注入的另一个依赖项类中时,您才可以这样做。RhinoMocks has the
AssertWasCalled
method which may serve the purpose of guaranteeing that a method calls another method... but I'm not sure you can do that on a private function of the same class you are unit testing. I think you could only do that if the two methods you wanted to stub were in another dependency class that was injected.尝试
Isolate.NonPublic.WhenCalled(object,"非公共方法").IgnoreCall
或 Isolate.Verify.NonPublic.WasCalled(object,"方法"..
try
Isolate.NonPublic.WhenCalled(object,"nonpublic method").IgnoreCall
or Isolate.Verify.NonPublic.WasCalled(object,"method"..