代码之家  ›  专栏  ›  技术社区  ›  auramo

用ruby模拟构造函数

  •  3
  • auramo  · 技术社区  · 16 年前

    我是一个Java开发者,和露比一起玩,喜欢它。我知道,由于ruby的元编程工具,我的单元测试变得更加干净,我不需要讨厌的模拟框架。我有一个班级需要 File 类的服务,在我的测试中,我不想触及真正的文件系统。在Java中,我会使用一些虚拟文件系统来更容易地“接缝”来传递假的对象,但在Ruby中,这显然是多余的。与Java世界相比,我所提出的似乎已经很不错了。在测试的类中,我有一个可选的构造函数参数:

    def initialize(file_class=File)
    

    当我需要打开类中的文件时,我可以这样做:

    @file_class.open(filename)
    

    这个调用要么指向真正的文件类,要么在我的单元测试中,它指向一个不触及文件系统的伪类。我知道一定有更好的方法来处理元编程?

    3 回复  |  直到 11 年前
        1
  •  11
  •   Brian Phillips    16 年前

    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)
    
    
        2
  •  1
  •   tomafro    16 年前

    在你概述的情况下,我建议你做的事情看起来不错。我知道这是詹姆斯·米德(摩卡咖啡的作者)提倡的一种技巧。没有必要仅仅为了它而进行元编程。 Here's what James has to say about it (还有一长串你可以尝试的其他技巧)

        3
  •  1
  •   Community skywinder    7 年前

    这对我来说是一个特别困难的挑战。在我得到的帮助下 this question ,还有一些额外的工作,这是我得到的解决方案。

    # 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