1

我使用 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")对内部工作假设过多,并且一旦我将其移至例如 resque 就会失败。

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

4

2 回答 2

1

there is a rule of thumb that you should "only mock the objects you own". In this case, it looks like you want to ensure that a compressed archive was created. You should probably have an object or method somewhere in your application who's sole responsibility is to perform this action.

Let's assume you have a method named create_archive that does this. With proper unit test coverage on create_archive you can simply verify that it was called from within your integration test. You should expect and verify that this method gets called, not the call to Kernel#system or Kernel#`. Those calls are implementation details, and you want to verify the logic (create_archive) instead.

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
于 2013-09-10T22:16:39.063 回答
0

您所做的是集成测试。您还需要一个低级单元测试,它不关心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
于 2013-08-21T09:45:54.383 回答