2016-03-08 86 views
0

我只是手动发现了一个迁移错误。我在模型中添加了一个新字段,并忘记将其添加到控制器的 _params方法中。结果新字段没有被保存到数据库中。在Rails中自动测试模型

一旦我注意到问题,就足以解决问题,但它让我想知道是否有方法在测试中检测到这一点。我会想象一个像解析模式并生成一组测试以确保所有字段都可以被写入并且可以读回相同数据的gem。

这是可以(或是)完成的事情吗?到目前为止,我的搜索引起了我很多有趣的阅读,但不是像这样的宝石...

+0

如果您要求人们找到第三方库来执行您想要的操作,请注意此类请求不属于Stack Overflow主题。请参阅[Stack Overflow帮助文件](http://www.stackoverflow.com/help)了解更多信息。如果你只是问你想要的是否可能,我很确定。也许这可能是你愿意为社区做贡献的宝石。 – MarsAtomic

回答

2

这是可以写你想要什么。遍历模型中的所有字段,生成反映这些字段的参数,然后在控制器上运行功能测试。问题是测试是脆弱的。如果你实际上不希望所有的字段都可以通过params写出来呢?如果您在标准模式之外的另一个控制器中引用模型,该怎么办?你将如何处理能够通过不同验证的生成数据?你要么必须确保你的应用程序只能以某种方式写入,否则这个测试将变得越来越复杂,以处理额外的边界情况。

我认为测试中的解决方案是试图保持简单;意识到你已经改变了系统,并且由于这种改变,相应的测试需要更新。在这种情况下,您需要更新受该模型影响的功能和单元测试。如果您严格遵守测试驱动设计,您将首先更新测试以产生失败的测试,然后实施更改。因此,希望在这种情况下更新的功能测试将失败。

在测试之外,您可能需要查看棉绒。本质上,你问的是,如果你传递给对象的方法的参数与签名不匹配,你是否可以捕获错误。当完全解析代码时(即在静态类型环境中编译),这更具可捕获性。

编辑 - 我跳过了LINTING的一个步骤,因为您还必须以某种方式编写代码,以使LINTER能够捕获它,例如更明确地传递给它的方法和参数。

+0

写得很好的答案。虽然像Rubucop这样的linders很擅长捕捉不良的习惯和常见的东西,但我并不真正了解linter在这种情况下会有什么帮助,因为你基本上都在研究所有采用'(hash = {},&block)'的ActiveRecord方法。编码错误。 – max

+1

我想建议一种可能的自动化方法来“免费”捕捉这些类型的错误,这是OP想要的,并且首先让Linter分析代码出现。我认为我更多地将其视为一种探索OP的方式,以防OP不熟悉。我想到的解决方案是改变编码风格并且更加明确,比如用明确的参数定义你自己的保存方法。在这种情况下,如果您没有传递正确数量的参数,则可以捕获一条棉绒。无可否认,这会导致样板代码并且看起来更像Java,所以......不是Rails的方式。 –

1

您可能想要考虑这样的宝石可能不存在,因为它在现实生活中并不实用或不实用。

从Active Record提供的反射方法中获取模型列非常简单。是的,你可以用它理论上自动运行循环中的一堆测试。

但实际上它只是不会削减它。在现实生活中,你不希望每列都是可分配的。这就是为什么你首先使用质量保护的原因。

并补充说明模型具有的各种约束和数据类型的复杂性。你最终会遇到一些非常复杂的事情,只会增加一些有限的测试。

如果您发现自己忽略了质量分配保护的属性,则应该尝试通过功能测试或集成测试覆盖控制器的该部分。

class ArticlesControllerTest < ActionController::TestCase 

    def valid_attributes 
    { 
     title: 'How to test like a Rockstar', 
     content: 'Bla bla bla' 
    } 
    end 

    test "created article should have the correct attributes" do 
    post :create, article: valid_attributes 
    article = Article.last 

    valid_attributes.keys.each do |key| 
     assert_equals article[key], valid_attributes[key] 
    end 
    end 
end