Ruby rspec在多个上下文之间传递变量的方法
我想知道在rspec中,在多个上下文(或多个it)之间传递变量的最佳方式是什么,但不使用全局变量 例如,我有: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
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的值
欢迎提出任何意见、建议和改进。
谢谢
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进行功能测试,其中这些示例(或者我更愿意称之为测试步骤)按顺序执行,通常需要一些示例的输出作为下一个示例的输入