给定一个构造函数,该构造函数预计会引发异常:
public class MyObject
{
public MyObject(String name)
{
if (String.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
this.Initialize();
}
protected virtual void Initialize()
{
// do stuff
}
}我将如何在Rhino中使用Machine.Fakes (默认情况下,我将迁移到Rhino)来模拟这个类,并测试它:
使用Moq,我可以模拟实际的MyObject类本身,并在模拟Callbase = true上设置属性,使其像普通类那样工作。
然后,我可以验证是否抛出了异常,并且没有用以下方法调用该方法:
// all pseudo code to prove my point of "creating an instance"
//
void when_creating_new_MyObject_with_null_Name_should_throw_Exception()
{
// arrange
Mock<MyObject> myObjectToTest = new Mock<MyObject>(String.Empty);
myObjectToTest.Callbase = true;
// act
Assert.Throws<ArgumentNullException>(() =>
var instance = myObjectToTest.Object;
);
}
void when_creating_new_MyObject_with_null_Name_should_not_call_Initialize()
{
// arrange
Mock<MyObject> myObjectToTest = new Mock<MyObject>(String.Empty);
myObjectToTest.Callbase = true;
// act
try
{
// creates an instance
var instance = myObjectToTest.Object;
}
catch {}
// assert
myObjectToTest.Verify(x => x.Initialize(), Times.Never());
}但是,我很难弄清楚如何使用MSpec w/赝品来模拟这个问题:
[Subject(typeof(MyObject), "when instantiating a new instance")
class with_null_Name
{
static MyObject myObjectToTest;
static Exception expectedException;
Establish context =()=>
myObjectToTest = An<MyObject>(String.Empty);
Because of; // I don't think there is anything to act on here?
It should_throw_Exception;
// how to capture exception with An<T>()?
It should_not_call_Initialize = () =>
myObjectToTest.WasNotToldTo(x => x.Initialize());
}我知道和使用Catch.Exception(...)通常在我的Because of行为。但是这个用例似乎不适用于此。
如有任何指示,将不胜感激。
谢谢!
免责声明:现实世界中的用例相当复杂,需要初始化的对象很重,使用缓存的支持成员非常昂贵。上面的代码只是一个简化的版本。
发布于 2013-07-24 16:29:49
就我个人而言,我不习惯使用模拟框架来模拟被测试单元中的东西。我使用模拟来使用依赖项注入来打破外部依赖关系。我绝不是这方面的专家,但我的直觉是,这是一个细粒度的细节,无法测试。
你说你的现实世界中有很多对象需要初始化;你不能嘲笑其中一个或多个对象并检查它们没有被调用吗?或者,使用依赖项注入一些可以设置标志的假对象。
这些建议在我看来都很难闻。最后,您知道如果您抛出了初始化未被调用的异常。我想我理解您正在努力确保一个bug不会在将来的编辑中出现,但是您实际上是在这里测试开发人员吗?我个人认为,如果提供了错误的数据,就足以验证异常是否会抛出。不过,我很想听听不同的意见。
发布于 2013-07-25 15:22:49
对我来说,不要用模拟的sut进行有意义的测试,模拟行为是由您在测试方法中定义的。你应该测试真实的对象。
在这种情况下,您应该只验证在提供错误数据时抛出异常。
我想你知道怎么做,但无论如何,这是密码:
[Subject(typeof (MyObject), "when instantiating a new instance")]
internal class with_null_Name
{
static MyObject myObjectToTest;
static Exception expectedException;
Because of = () => expectedException = Catch.Exception(
() => myObjectToTest = new MyObject(String.Empty));
It should_fail = () => expectedException.ShouldNotBeNull();
}https://stackoverflow.com/questions/17837819
复制相似问题