我正在RSpec中编写单元测试,以检查在方法移动或删除之后创建的实例是否不存在。
例如,我有一个Airport类和一个Plane类,而Airport = Airport.new初始化时存储了一个Plane.new实例。当#takeoff方法运行时,Plane.new存储在其他地方或#pop'ped。
我如何证明此Plane.new的确切实例未包含在机场中?有没有办法捕获方法所作用的对象的ID?
我正在考虑的测试将是这样的:
describe Airport do
it "confirms plane is not there after #takeoff" do
airport = Airport.new
airport.takeoff
expect(airport).not_to include(*ID OF PLANE MOVED/POPPED*)
end
end
将来,机场可以使用任意数量的飞机进行初始化,因此,我相信有必要使用ID进行确认,但很高兴听到其他消息。
答案 0 :(得分:3)
通常,单元测试会测试公共API,因此问题应该是:“机场有办法告诉我们地面上有哪些飞机”。如果那是重要的信息,就必须有这样的方法。例如,您可能有一个名为planes
的方法,然后仅检查该集合中是否包含特定实例:
expect(airport.planes).not_to include(plane)
另一种方法可能是,该飞机对当前所在的机场进行参考,起飞后将其设置为零。因此,您最终要检查该引用:
expect(plane.airport).to be_nil
但是无论如何,这全都与数据建模有关,而不是与测试框架有关
答案 1 :(得分:1)
这是我的评论中提到的使用object_id的示例。 我的rspec技巧有些生锈,但是希望您能理解。
require 'rspec'
class Plane
def initialize(some_property)
@some_property = some_property
end
end
class Airport
attr_reader :planes_ready_for_takeoff, :planes_in_fight
def initialize()
@planes_ready_for_takeoff = [Plane.new("plane_foo"), Plane.new("plane_bar")]
@planes_in_fight = []
end
def takeoff()
@planes_in_fight << @planes_ready_for_takeoff.shift
end
end
describe "Airport" do
before(:context) do
@airport = Airport.new
@first_plane = @airport.planes_ready_for_takeoff.first
end
it "confirms a plane is ready for takeoff" do
expect(@airport.planes_ready_for_takeoff.map { |p| p.object_id}).to include(@first_plane.object_id)
end
describe "#takeoff" do
it "remove the first plane from the list of planes ready to take off" do
@airport.takeoff
expect(@airport.planes_ready_for_takeoff.map { |p| p.object_id}).not_to include(@first_plane.object_id)
end
end
end
顺便说一句,我认为您甚至不需要映射到object_id,因为我认为include使用==
应该检查确切的对象。