Ruby rspec在多个上下文之间传递变量的方法

Ruby rspec在多个上下文之间传递变量的方法,ruby,rspec,rspec2,elixir,Ruby,Rspec,Rspec2,Elixir,我想知道在rspec中,在多个上下文(或多个it)之间传递变量的最佳方式是什么,但不使用全局变量 例如,我有: describe "My test" do let(:myvar) { @myvar = 0 } context "First test pass" do it "passes" do myvar = 20 expect(myvar).to eq(20) end end

我想知道在rspec中,在多个上下文(或多个it)之间传递变量的最佳方式是什么,但不使用全局变量

例如,我有:

describe "My test" do
    let(:myvar) { @myvar = 0 }

    context "First test pass" do
        it "passes" do
            myvar = 20
            expect(myvar).to eq(20)
        end
    end

    context "Second test pass" do
        it "passes" do
            expect(myvar).to eq(20)
        end
    end
end
现在,显然,这对let不起作用,因为在新的上下文中,myvar变量将回到初始状态,即=0。 我需要在两个上下文之间“缓存状态”的机制,这将在第二个上下文中为我提供myvar=20的值

欢迎提出任何意见、建议和改进。 谢谢

  • 发生的事情并不是你所想的
  • 您希望发生的事情打破了“单元测试”的方法论
  • 让我解释一下#2第一单元测试测试用例应该能够独立工作,这意味着它们应该在一起运行、分开运行以及以任何顺序运行时工作。。。以至于有些单元测试框架(如中的默认框架)并行运行测试用例

    至于#1-当您编写
    myvar=20
    时,您没有为
    let(:myvar){@myvar=0}
    赋值,您只需创建一个局部变量,它将覆盖方法内对
    myvar
    的所有调用,但在方法外不可用(
    myvar
    将返回
    0

    即使您将设置
    @myvar=20
    (除非您在第一次调用
    myvar
    之前进行设置),
    myvar
    仍将返回
    0
    ,因为
    let
    函数使用的是memento模式,这意味着它将被调用一次,后续调用将返回最初返回的值(在这种情况下
    0
    ):


    我只是遇到了同样的问题。我是如何通过使用factory_girl gem解决的

    以下是基本知识:

    创建工厂:

    require 'factory_girl'
    require 'faker' # you can use faker, if you want to use the factory to generate fake data
    
    FactoryGirl.define do
      factory :generate_data, class: MyModule::MyClass do
        key 100 # doesn't matter what you put here, it's just a placeholder for now
        another_key 'value pair'
      end
    end
    
    现在,在制作工厂后,您需要制作一个如下所示的模型:

    Module MyModule
      class MyClass
        #for every key you create in your factory you must have a corresponding attribute accessor in the model.
        attr_accessor :key, :another_key
    
        #you can also place methods here to call from your spec test, if you wish
        # def self.test
            #some test
        # end
      end
    end
    
    describe "My test" do
        let(:myvar) { @myvar }
    
        context "First test pass" do
            it "passes" do
                @myvar.key = 20 #when you do this you set it now from 100 to 20
                expect(@myvar.key).to eq(20)
            end
        end
    
        context "Second test pass" do
            it "passes" do
                expect(@myvar.key).to eq(20) #it should still be 20 unless you overwrite that variable
            end
        end
    end
    
    现在回到您的示例,您可以执行以下操作:

    Module MyModule
      class MyClass
        #for every key you create in your factory you must have a corresponding attribute accessor in the model.
        attr_accessor :key, :another_key
    
        #you can also place methods here to call from your spec test, if you wish
        # def self.test
            #some test
        # end
      end
    end
    
    describe "My test" do
        let(:myvar) { @myvar }
    
        context "First test pass" do
            it "passes" do
                @myvar.key = 20 #when you do this you set it now from 100 to 20
                expect(@myvar.key).to eq(20)
            end
        end
    
        context "Second test pass" do
            it "passes" do
                expect(@myvar.key).to eq(20) #it should still be 20 unless you overwrite that variable
            end
        end
    end
    
    正如其他人所说,这不是正确的单元测试方法。但是,我们如何知道您是否在进行单元测试。所以,我不作判断。
    无论如何,如果您有其他解决方案,祝您好运!另一种简单的方法是在描述上下文中定义“局部变量”。 “局部变量”将贯穿整个描述过程,运行时期间的任何更改都会影响它,因此会对其进行更改

    比如说

    describe 'tests' do
        context 'Sharing a variable across tests' do
            var = 1
            puts var
    
            it "it one. var = #{var}" do
                var = var*2
                puts var
            end
            it "it two" do
                puts var
            end
        end
    end 
    
    输出

    1
    2
    1
    

    不在上下文之间传递变量更好。如果需要上下文,请在上下文块中创建它。简而言之,让我们可以定义起始状态(无论是对象还是简单类型)哪个可以通过后续上下文使用,但不能更改?@Bakirjusuffegovic-否,它是为每个测试用例重新创建的,但不是在一个测试用例中(不止一次)这意味着let是在示例之间重新创建的,但不是在同一个示例中创建的(当多次使用时).Guess let不能用于我需要的机制,它是在示例之间“缓存某个变量的状态”的能力。我理解单元测试不应该以这种方式工作(测试应该是独立的),但我使用RSpec进行功能测试,其中这些示例(或者我更愿意称之为测试步骤)按顺序执行,通常需要一些示例的输出作为下一个示例的输入