4

我是一名 Java 开发人员,正在玩弄 Ruby,并且喜欢它。我了解到,由于 Ruby 的元编程工具,我的单元测试变得更加清晰,并且我不需要讨厌的模拟框架。我有一个需要File类服务的类,在我的测试中我不想接触我真正的文件系统。在 Java 中,我会使用一些虚拟文件系统来更轻松地“接缝”来传递假对象,但在 Ruby 中,这显然是矫枉过正。与 Java 世界相比,我想出的东西似乎已经很不错了。在我的测试类中,我有一个可选的构造函数参数:

def initialize(file_class=File)

当我需要在课堂上打开文件时,我可以这样做:

@file_class.open(filename)

并且调用转到真正的文件类,或者在我的单元测试的情况下,它转到不接触文件系统的假类。我知道必须有更好的方法来使用元编程来做到这一点?

4

3 回答 3

12

Mocha ( http://mocha.rubyforge.org/ ) 是一个非常好的 ruby​​ 模拟库。根据您实际想要测试的内容(即,如果您想伪造 File.new 调用以避免文件系统依赖性,或者您想验证是否将正确的参数传递给 File.new),您可以这样做像这样的东西:


require 'mocha'

mock_file_obj = mock("My Mock File") do
  stubs(:some_instance_method).returns("foo")
end

File.stubs(:new).with(is_a(String)).returns(mock_file_obj)

于 2008-09-16T13:36:51.757 回答
1

This is a particularly difficult challenge for me. With the help I received on this question, and some extra work on my behalf, here's the solution I arrived at.

# lib/real_thing.rb
class RealThing
  def initialize a, b, c
    # ...
  end
end

# test/test_real_thing.rb
class TestRealThing < MiniTest::Unit::TestCase

  class Fake < RealThing; end

  def test_real_thing_initializer
    fake = mock()
    Fake.expects(:new).with(1, 2, 3).returns(fake)
    assert_equal fake, Fake.new(1, 2, 3)
  end

end
于 2013-06-21T19:54:51.400 回答
1

在您概述的情况下,我建议您正在做的事情看起来不错。我知道这是 James Mead(Mocha 的作者)提倡的一种技术。没有必要仅仅为了它而进行元编程。 以下是詹姆斯对此的看法(以及您可以尝试的一长串其他技术)

于 2008-09-16T15:30:30.127 回答