给定一个预期会抛出异常的构造函数:
public class MyObject
{
public MyObject(String name)
{
if (String.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
this.Initialize();
}
protected virtual void Initialize()
{
// do stuff
}
}
我将如何使用 Machine.Fakes 和 Rhino(默认设置,我正在迁移到 Rhino)来模拟这个类,并测试它:
- 它抛出预期的异常
- 它不调用 Initialize()
使用 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());
}
但我无法弄清楚如何使用带有 Fakes 的 MSpec 来模拟它:
[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
行为中正常使用。但是这个用例似乎不适用于那个。
任何指针将不胜感激。
谢谢!
免责声明:现实世界的用例非常复杂,需要初始化大量对象,缓存的支持成员非常昂贵。上面的代码只是一个简化版本。