您如何测试是否将调用Ruby析构函数?

迈克·HR

我创建了一个我想挂在文件描述符上的类,并在实例经过GC处理时将其关闭。

我创建了一个看起来像这样的类:

class DataWriter
  def initialize(file)
    # open file
    @file = File.open(file, 'wb')
    # create destructor
    ObjectSpace.define_finalizer(self, self.class.finalize(@file))
  end

  # write
  def write(line)
    @file.puts(line)
    @file.flush
  end

  # close file descriptor, note, important that it is a class method
  def self.finalize(file)
    proc { file.close; p "file closed"; p file.inspect}
  end
end

然后,我尝试像这样测试析构函数方法:

RSpec.describe DataWriter do
  context 'it should call its destructor' do
    it 'calls the destructor' do
      data_writer = DataWriter.new('/tmp/example.txt')
      expect(DataWriter).to receive(:finalize)
      data_writer = nil
      GC.start
    end
  end
end

运行此测试时,即使将“ filecloses”和“ file.inspect”一起打印,测试也会失败,并显示以下输出:

1) DataWriter it should call its destructor calls the destructor
     Failure/Error: expect(DataWriter).to receive(:finalize)

       (DataWriter (class)).finalize(*(any args))
           expected: 1 time with any arguments
           received: 0 times with any arguments
     # ./spec/utils/data_writer_spec.rb:23:in `block (3 levels) in <top (required)>'
戴夫·史威斯古斯

finalize在中调用initialize,返回proc,然后再也不会调用它,因此您不能期望在完成时调用它。实例完成后会调用proc要进行检查,请让proc调用方法而不是自己完成工作。通过:

class DataWriter
  # initialize and write same as above

  def self.finalize(file)
    proc { actually_finalize file }
  end

  def self.actually_finalize(file)
    file.close
  end

end

RSpec.describe DataWriter do
  context 'it should call its destructor' do
    it 'calls the destructor' do
      data_writer = DataWriter.new('/tmp/example.txt')
      expect(DataWriter).to receive(:actually_finalize)
      data_writer = nil
      GC.start
    end
  end
end

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章