使用RSpec测试DAO

时间:2015-05-18 16:51:41

标签: ruby rspec sequel

我正在参与一个涉及红宝石,续集和sinatra的项目。我读到了要使用的测试框架,RSpec似乎是社区最常用的。

该项目包含一个CRUD应用程序,使用DAO作为持久性模式。

require 'sequel'

DB = Sequel.sqlite
DB.create_table :foos do
  primary_key :id
  int :foo_attribute1
  int :foo_attribute2
end

class Foo
  attr_accessor :id, :foo_attribute1, :foo_attribute2
end

module FooDAO
  extend self

  def save(f)
    DB[:foos].insert(foo_attribute1: f.foo_attribute1, foo_attribute2: f.foo_attribute2)
  end

  def [](id)
    DB[:foos].where(id: id).first
  end

  def update(f)
    DB[:foos].where(id: f.id).update(foo_attribute1: f.foo_attribute1, foo_attribute2: f.foo_attribute2)
  end

  def count
    DB[:foos].count
  end
end

describe FooDAO do
  context 'save' do
    f = Foo.new
    f.foo_attribute1 = 1
    f.foo_attribute2 = 2
    FooDAO.save f
    it { expect(FooDAO.count).to eq 1 }
  end

  context 'get' do
    it { expect(FooDAO[1][:foo_attribute1]).to eq 1 }
    it { expect(FooDAO[1][:foo_attribute2]).to eq 2 }
  end

  context 'update' do
    f = Foo.new
    f.id = 1
    f.foo_attribute1 = 2
    f.foo_attribute2 = 3
    FooDAO.update f
    it { expect(FooDAO[1][:foo_attribute1]).to eq 2 }
    it { expect(FooDAO[1][:foo_attribute2]).to eq 3 }
  end
end

在这种情况下,get上下文不会传递示例。但如果我评论update上下文,他们会。

我还发现,如果我更改get上下文,它会全部传递

context 'get' do
  h = FooDAO[1]
  it { expect(h[:foo_attribute1]).to eq 1 }
  it { expect(h[:foo_attribute2]).to eq 2 }
end

1 个答案:

答案 0 :(得分:0)

这与您在上下文块中而不是在test语句(it块中)中包含其他代码的事实有关。

试试这个:

describe FooDAO do
  context 'save' do
    it "saves a Foo" do
      original_count = FooDAO.count
      f = Foo.new
      f.foo_attribute1 = 1
      f.foo_attribute2 = 2
      FooDAO.save f
      expect(FooDAO.count).to eq(original_count + 1)
    end
  end

  context 'get' do
    let!(:foo) do
      f = Foo.new
      f.foo_attribute1 = 1
      f.foo_attribute2 = 2
      FooDAO.save f
      f
    end

    it { expect(FooDAO[foo.id][:foo_attribute1]).to eq 1 }
    it { expect(FooDAO[foo.id][:foo_attribute2]).to eq 2 }
  end

  context 'update' do
    let!(:foo) do
      f = Foo.new
      f.id = 1
      f
    end

    before(:each)
      foo.foo_attribute1 = 2
      foo.foo_attribute2 = 3
      FooDAO.update foo
    end

    it { expect(FooDAO[1][:foo_attribute1]).to eq 2 }
    it { expect(FooDAO[1][:foo_attribute2]).to eq 3 }
  end
end