0

我有一个嘲笑的问题。我知道只有公共方法应该被嘲笑。但是当在公共方法中调用了私有方法,而这个私有方法是从文件中获取数据时,我该怎么办呢?我想模拟这个私有方法,以便继续测试公共方法。

我可以将其公开以进行测试,但这没有任何意义,因为它是私有的。我还可以将所有内容移到另一个类中并在那里公开函数,但是对主类中对象的引用应该是私有的。

我正在使用犀牛模拟。

谢谢你的帮助 :)

4

5 回答 5

3

如果您将执行文件读取的功能放入一个类中,例如

FileReader : IFileReader

然后将 IFileReader 作为 arg 传递给构造函数。然后你可以嘲笑它

于 2009-06-24T10:30:17.410 回答
0

其他建议的替代方法是使您的代码模板化并接收一个 FileReader 类型,该类型可以在您的类的整个方法中使用。

template <class FileReader>
class SomeClass
{
  private: void doSomething()
  {
    FileReader fileReader;
    // Do something
  }
};

另一种方法是将方法传递给返回 FileReader 实现的 SomeClass 构造函数。这可以在整个类中使用,类似于使用模板的方式,但是这样做您仍然会从 IFileReader 派生 MockFileReader。

其中任何一个的问题是无法在 FileReader 上执行单元测试,因为 SomeClass 无法访问它。

注意上面的代码是 C++,但我知道这两种方法都可以用 C#。

于 2009-06-24T12:23:48.957 回答
0

无论这是服务还是商业实体,请确保您同意自己的观点。

服务通常被认为是它使用一组业务实体来完成某些任务,并且它本身并不维护持久数据。

业务实体是您的问题域中的一个单元,您希望在概念上坚持下去。

如果你发现它是一个服务,你应该在构建服务时以某种方式注入依赖。通常它可以有一个这样的构造函数: public MyService(IFileObject)

从 main 构造时: var service = new MyService(MyRealFile)

从测试设置构造时: var service = new MyService(MyMockedFiled)

如果您发现您正在测试的实际上是一个业务实体,那么您应该避免给该实体一个依赖项。您通常会后退一步,在您自己和业务实体之间构建一个服务类。该服务明确地向业务实体提供其所有必要的数据。在您的情况下,这意味着该服务为实体提供了它应该通过读取文件来学习的任何内容。

因此,服务依赖于文件系统,甚至可以使用另一个(专用)文件读取器业务实体来读取文件。如果您在系统的其他地方使用业务实体,您将永远不会希望进行恶意依赖调用。他们的代码变成了上下文绑定的,这是你想要避免的。业务实体应快速、离散、明确且响应迅速。

您的单元测试应针对服务,该服务可能会通过注入接收依赖项。如果您发现您正在对业务实体进行单元测试,那么您缺乏服务级别。

于 2009-06-24T12:51:15.720 回答
0

感谢您的回答,我的 cookie 被删除了。我使用了第一个答案并在代码中进行了一些更改。效果很好 :)

于 2009-06-25T09:52:36.823 回答
0

拉出文件依赖并在构造函数中传入一个 IFileSomething 接口。然后模拟 IFileSomething 并对其设置期望。

于 2009-06-24T10:28:43.933 回答