首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Machine.Fakes确保构造函数不调用本地方法?

如何使用Machine.Fakes确保构造函数不调用本地方法?
EN

Stack Overflow用户
提问于 2013-07-24 15:02:02
回答 2查看 1K关注 0票数 2

给定一个构造函数,该构造函数预计会引发异常:

代码语言:javascript
复制
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)来模拟这个类,并测试它:

  1. 它将引发预期的异常。
  2. 它不调用Initialize()

使用Moq,我可以模拟实际的MyObject类本身,并在模拟Callbase = true上设置属性,使其像普通类那样工作。

然后,我可以验证是否抛出了异常,并且没有用以下方法调用该方法:

代码语言:javascript
复制
// 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/赝品来模拟这个问题:

代码语言:javascript
复制
[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行为。但是这个用例似乎不适用于此。

如有任何指示,将不胜感激。

谢谢!

免责声明:现实世界中的用例相当复杂,需要初始化的对象很重,使用缓存的支持成员非常昂贵。上面的代码只是一个简化的版本。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-24 16:29:49

就我个人而言,我不习惯使用模拟框架来模拟被测试单元中的东西。我使用模拟来使用依赖项注入来打破外部依赖关系。我绝不是这方面的专家,但我的直觉是,这是一个细粒度的细节,无法测试。

你说你的现实世界中有很多对象需要初始化;你不能嘲笑其中一个或多个对象并检查它们没有被调用吗?或者,使用依赖项注入一些可以设置标志的假对象。

这些建议在我看来都很难闻。最后,您知道如果您抛出了初始化未被调用的异常。我想我理解您正在努力确保一个bug不会在将来的编辑中出现,但是您实际上是在这里测试开发人员吗?我个人认为,如果提供了错误的数据,就足以验证异常是否会抛出。不过,我很想听听不同的意见。

票数 2
EN

Stack Overflow用户

发布于 2013-07-25 15:22:49

对我来说,不要用模拟的sut进行有意义的测试,模拟行为是由您在测试方法中定义的。你应该测试真实的对象。

在这种情况下,您应该只验证在提供错误数据时抛出异常。

我想你知道怎么做,但无论如何,这是密码:

代码语言:javascript
复制
[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();
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17837819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档