使用Object.send(:remove_const,'MyClass')的Ruby问题

时间:2019-01-21 16:47:40

标签: ruby rspec

我想“重新初始化”我的User类,所以我的每个RSpec示例中都有一个新状态。我尝试致电remove_const

before(:each) do
  Object.send(:remove_const, 'User')
  load 'user.rb'
end

describe 'initializer' do
  it 'creates an user' do
    user = User.new("jules", "jules@gg.k")
    expect(user.class).to eq(User)
  end

  it 'saves @email as instance variable' do
    email = "jules@gg.com"
    user = User.new("jules", email)
    expect(user.email).to eq(email)
  end

  # ...
end

但它返回:

NameError: constant Object::User not defined

我的User类看起来像这样:

class User
  attr_accessor :name, :email
  @@user_list = []
  @@user_count = 0

  def self.user_count
    @@user_count
  end

  def self.all
    @@user_list
  end

  def initialize(name, email)
    @email = email
    @name = name
    @@user_count += 1
    @@user_list << self
  end
end

2 个答案:

答案 0 :(得分:2)

我看到两个选择:

  1. 仅在实际定义了常量的情况下将其删除:

    if Object.const_defined?(:User)
      Object.send(:remove_const, :User)
      load 'user.rb' # <- you may have to adjust the path
    end
    
  2. User添加类方法以清除内存用户“数据库”:

    class User
      def self.clear
        @@user_list = []
        @@user_count = 0            
      end
    end
    

    然后致电:

    before(:each) do
      User.clear
    end
    

我会选择选项#2。

答案 1 :(得分:-1)

require_relative '../lib/user'

describe User do

    before(:each) do
            Object.send(:remove_const, 'User')
            load 'user'
    end 

    describe 'initializer' do

        it 'creates an user' do
            user = User.new("jules", "jules@gg.k")
            expect(user.class).to eq(User)
        end

        it 'saves @email as instance variable' do
            email = "jules@gg.com"
            user = User.new("jules", email)
            expect(user.email).to eq(email)
        end

        it 'adds one to the @@user_count global variable' do
            count = User.user_count
            user = User.new("jules", "email@email.email")
            expect(User.user_count).to eq(count+1)
        end

    end

    describe 'classe method' do

        describe 'all' do
            it 'should return a list of names of all users' do
                user1 = User.new("jacques", "jacky@chan.fr")
                user2 = User.new("phil", "ph@il.ipe")
                expect(User.all.map! {|k| k.name}).to eq(["jacques", "phil"])
            end
        end

        describe 'find_by_email' do
            it 'should return return a name if user exists and nil otherwise' do
                user1 = User.new("jacques", "jacky@chan.fr")
        user2 = User.new("phil", "ph@il.ipe")
                expect(User.find_by_email("jacky@chan.fr")).to eq("jacques")
            end
        end
    end
end