FactoryGirl Rspec实际上并未将记录保存到测试数据库中

时间:2014-03-22 05:14:40

标签: ruby-on-rails ruby rspec ruby-on-rails-4 factory-bot

我正在尝试使用FactoryGirl在Rspec中生成一个成功的测试。

规范文件:

require 'spec_helper'

describe Manager::Synchronization do

    it "contains all parameters" do
        build_stubbed(:synchronization, elapsed_time: nil).should_not be_valid
        build_stubbed(:synchronization, updated_records: nil).should_not be_valid
    end

    it "processes asset downloads" do
        # Normally created via delayed_job calling method download_assets_for,
        # we are going to do it right now instead
        p = create(:photograph)
        s = build(:synchronization)
        puts "SLEEPING"
        # By this point, the Photograph has been saved and should appear
        # in the test database. If I write below: puts Manager::Photograph.all.inspect,
        # it gives me a result set that shows the Photograph was indeed saved
        # to the database. However s.download_assets_for(p.class, p.id) raises an
        # error ("Couldn't find Manager::Photograph at id:1").
        sleep 10
        # Expect no errors if the instance should be found
        expect { s.download_assets_for(p.class, p.id) }.to_not raise_error
        # Expect this error
        expect { s.download_assets_for(p.class, 0) }.to raise_error(RuntimeError, "Couldn't find #{ p.class } at id:0")
    end

end

正如我在spec文件中的评论所示,我通常希望在所有帐户都存在的模型上调用download_assets_for不会引发错误。 download_assets_for使用RestClient向' master'进行API调用。服务器 - 在这种情况下是包含相同测试数据库的相同应用程序;我刚把照片保存到的那个。它将响应发送回调用它的方法。但是,当服务器收到请求(由RestClient发送)时,创建的照片不会出现在数据库中。我已经通过在睡眠10期间刷新MySQL Workbench中的MySQL查询来证实这一点。

总而言之:Rspec告诉我,当记录真的没有时,它会被保存。我必须修改我的download_assets_for方法,以检查我是否在测试环境中,只返回不同的结果,而不是使用RestClient - 但这感觉就像一个邋解决方法。主要问题是:为什么Rspec说这个记录确实存在,当它真的没有?

测试我所谈论的最简单的方法是:

1)打开MySQL工作台,然后转到测试数据库/表,然后查看所有行。这一点应该没有行,因为测试数据库应该是空的。

2)进行Rspec测试,在其中使用FactoryGirl create电话(或者是Rspec?)。

3)在致电create之后,puts刚刚创建的记录。它应显示为已保存。

4)在此之后立即进行一次睡眠呼叫,这样您就可以手动点击返回MySQL工作台并重新加载查询。你应该看不到任何记录。也就是说,Rspec说它是在没有创建的时候创建的。

1 个答案:

答案 0 :(得分:1)

FactoryGirl,单元测试中的数据库测试通常用于正在运行的测试的数据库的内部表示,并且不保证更改数据库的状态在测试之外。

您描述的架构在测试中调用REST调用。这在respc中非常discouraged

  

在测试运行期间对外部服务的请求可能会导致多个问题   的问题:

     
      
  • 由于连接问题,测试间歇性地失败。
  •   
  • 测试套件显着变慢。
  •   
  • 在第三方网站上达到API费率限制(例如   微博)。
  •   
  • 服务可能尚不存在(仅有文档)。
  •   
  • 服务没有沙盒或登台服务器。
  •   

恕我直言,您不应将其作为数据库用例进行测试,而应将其作为RestClient用例进行测试,因为您的代码不会直接调用数据库,而是调用REST API。

编写一个测试,为测试的客户端存储REST API,另一个设置数据库,以测试REST API的服务器端(测试REST调用是否收到预期结果)。