【问题标题】:Ruby gem: writing tests for api wrapperRuby gem:为 api 包装器编写测试
【发布时间】:2012-06-11 00:31:47
【问题描述】:

我正在为将用于多个应用程序的 API 包装器编写一个 gem。我无法控制这个 API,但我确实有一个开发环境,我可以在不影响生产的情况下搞砸。

你会如何为这个 gem 编写测试?

示例:考虑方法 add_customer,它采用多个参数(姓名、电子邮件等),其中电子邮件是唯一的。

如果我编写一个测试,插入一个带有电子邮件 a@gmail.com 的客户。第二次,虽然我的 gem 工作正常,但这个测试会失败。

【问题讨论】:

    标签: ruby testing gem


    【解决方案1】:

    通常,您希望为正在运行的每个测试清理数据库。我们正在使用 DatabaseCleaner gem 在 ruby​​ 中执行此操作。基本上在我们运行整个套件之前,我们会彻底清理数据库

    DatabaseCleaner.clean_with :truncation
    

    这需要一些时间,具体取决于您的数据库。之后我们使用事务策略来保持它更快

    DatabaseCleaner.strategy = :transaction
    

    这意味着在每个规范之前,在数据库中启动一个事务(创建一个保存点)并且测试在这个事务中运行。测试完成后,发出回滚,下一个规范再次拥有一个干净的数据库。查看https://github.com/bmabey/database_cleaner

    如果您确实需要在同一规范中创建两个这样的记录,那么您将需要创建某种计数器。比如:

    class Counter
      def initialize
        @count = 0
      end
    
      def email
        @count += 1
        "something_cool#{@count}@whatever.com"
      end
    end
    

    然后使用此计数器每次都为您提供唯一的电子邮件。查看 FactoryGirl gem https://github.com/thoughtbot/factory_girl/wiki/Usage 并查找序列可能是值得的。如果您正在构建一个小型 gem,那么您可能不想添加很多依赖项。祝你好运。一路TDD!

    无法控制系统的所有部分会导致更大的问题。在单元测试中,您可以愉快地去除所有外部 API,只返回预期的结果。但当然,如果 API 发生变化,这仍然会通过。分布式系统的集成测试是一个复杂的问题,基本上你需要像系统范围的事务这样的东西,它将系统的所有部分都置于原始状态。既然你没有那个控制权,我就放弃了。

    【讨论】:

    • 感谢您的回复,但我的问题是因为我无法控制外部 API。所以我不能在上面运行数据库清理器。我已经将 FactoryGirl 用于我的 Rails 应用程序,但在这个特定的 gem 中,我根本无法访问外部 API 数据。
    • 那么你面临一个大问题。在单元测试中,您可以愉快地去除所有外部 API,只返回预期的结果。但当然,如果 API 发生变化,这仍然会通过。分布式系统的集成测试是一个复杂的问题,基本上你需要像系统范围的事务这样的东西,它将系统的所有部分都置于原始状态。既然你没有那个控制权,我就放弃了。
    • 感谢您的回复。您的评论应该是这个问题的答案。如果您编辑它,我将标记为答案。
    猜你喜欢
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    相关资源
    最近更新 更多