Ruby 测试期望运行一个命令

Posted

技术标签:

【中文标题】Ruby 测试期望运行一个命令【英文标题】:Ruby testing expect a command to be ran 【发布时间】:2013-08-21 08:50:42 【问题描述】:

我使用 Minitest 和 Mocha 测试我的 Rails 应用程序以进行单元测试和集成测试,并想测试是否使用某些参数调用命令行命令。

说,我有课:

class Provisioning::Backup
  def create(path)
    system("tar -czf #path bar.tar.gz")
  end
end

我的测试只有想知道带有这些参数的命令是否运行。而不是它是否使用system() 或它的替代品``。甚至通过resque等。我想测试外部,而不是内部实现。

因此,我对 *test/integration/user_requests_backup_test.rb* 中的当前解决方案不满意:

class UserRequestsBackupTest < ActionDispatch::IntegrationTest
  test "requests for a backup runs a backup-script" do
    contact = contacts(:harry)
    site = contact.sites.first

    Provisioning::Backup.expects(:system).with("tar -xzf foo bar")

    post "/v1/sites/#site.id/backups"
    assert_response :success
  end

  # backup is already pending
  # backup fails
end

这可行,但断言实现而不是行为,因为Provisioning::Backup.expects(:system).with("tar -xzf foo bar") 对内部工作假设过多,并且一旦我将其移至例如回复

我还有哪些其他选择?有没有办法模拟或存根并期望 system 在较低级别?是否存在允许以更通用的方式模拟和预期命令的模式或 gem?

【问题讨论】:

【参考方案1】:

有一条经验法则,您应该“只模拟您拥有的对象”。在这种情况下,您似乎希望确保创建了压缩存档。您可能应该在应用程序的某个地方有一个对象或方法,其唯一责任是执行此操作。

假设您有一个名为create_archive 的方法来执行此操作。在create_archive 上使用适当的单元测试覆盖率,您可以简单地验证它是从您的集成测试中调用的。 您应该期望并验证是否调用了此方法,而不是调用 Kernel#systemKernel#`。这些调用是实现细节,您想验证逻辑 (create_archive)。

class UserRequestsBackupTest < ActionDispatch::IntegrationTest
  test "requests for a backup runs a backup-script" do
    contact = contacts(:harry)
    site = contact.sites.first

    Provisioning::Backup.expects(:create_archive)

    post "/v1/sites/#site.id/backups"
    assert_response :success
  end
end

【讨论】:

【参考方案2】:

您所做的是集成测试。您还需要一个不关心 system 方法的结果的低级单元测试,但要确保它会被正确调用。

我只知道使用 rspec-mock 模块的 Rspec 方法,但不知道 minitest。

describe Provisioning::Backup do
  subject  Provisioning::Backup.new 

  it "calls system method correctly" do
    subject.should_receive(:system).with('tar -czf #path bar.tar.gz')
    subject.create
  end
end

【讨论】:

是的,我也有单元测试来测试方法等等。我的问题是我希望我的集成测试测试较少的实现,因为我正在单元测试中测试该实现。我的问题是关于如何 /not/ 在我的集成测试中测试实现。

以上是关于Ruby 测试期望运行一个命令的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 不运行单元测试

如何让 Bamboo 期望任务的不同返回码?

如何在 Ruby Cucumber 中计算运行场景的标签?

在Ruby脚本中运行命令行命令

Ruby基准测试一条多次运行的线[关闭]

如何在 Ruby 2.2 上运行现有的测试代码