简体   繁体   English

Rspec测试,用于测试父资源中嵌套资源的创建控制器

[英]Rspec test for testing create controller of nested resource inside parent resource

My Rails API app has two resources: article (parent) and annotation (child). 我的Rails API应用程序具有两个资源:文章(父级)和注释(子级)。 I want to test that, when a parent is created, any children if specified are also created. 我想测试一下,当创建父对象时,是否还会创建任何子对象(如果指定)。 So I want to test this creation INSIDE the parent's create controller test, in additional to the child's create controller test itself. 因此,除了孩子的创建控制器测试本身之外,我还要在父级的创建控制器测试中测试此创建。

I've gotten the JSON request to work fine but I'm not sure how to structure my RSpec test 我已经收到JSON请求,但是我不确定如何构建我的RSpec测试

{
  "article": {
    "original_language": "ja",
    "title": "日本のコンビニが中東で初めて店を開く",
    "body": "コンビニの会社「セブン-イレブン・ジャパン」は13日、中東のUAE=アラブ首長国連邦のドバイに新しい店を開きました。日本のコンビニが中東に店を開くのは初めてです。\nUAEには24時間開いている店がほとんどありませんでした。このため、UAEの中のアブダビ首長国の王族(=王と王の親類)が新しいやり方の店を開いてほしいと頼んでいました。\n新しい店では、特に弁当やおにぎりなどを売りたいと考えています。UAEの人が好きなインドのスパイスを入れたり、大きなソーセージをのせたりしたおにぎりも作りました。新しい店の社長は「UAEにはいろいろな国の人たちが来ています。お客様がみんな喜ぶような店にしたいです」と話していました。\nセブン-イレブン・ジャパンは、これから3年でUAEに100の店を開く予定です。",
    "source_name": "NHK Easy News",
    "source_url": "http://www3.nhk.or.jp/news/easy/k10010269131000/k10010269131000.html",
    "privacy_status": 1,
    "scheduled_date": null,
    "level": 3,
    "annotations": [
      {
        "destination_language": "en",
        "authority_level": 1,
        "source_text": "コンビニ",
        "location_start": 1,
        "location_end": 5,
        "category": 0,
        "definition": "Convenience Store",
        "reading": null,
        "translation": null,
        "usage_note": "Convenience stores are everywhere in Japan. Most open 24/7. The big chains are 7/11, Lawson, Family Mart, Sunkus, and Circle K.",
        "specific_note": null,
        "paragraph_id": 1
      },
      {
        "destination_language": "en",
        "authority_level": 1,
        "source_text": "コンビニ",
        "location_start": 1,
        "location_end": 5,
        "category": 0,
        "definition": "Convenience Store",
        "reading": null,
        "translation": null,
        "usage_note": "Convenience stores are everywhere in Japan. Most open 24/7. The big chains are 7/11, Lawson, Family Mart, Sunkus, and Circle K.",
        "specific_note": null      }
    ]
  }
}

Here is my attempt so far. 到目前为止,这是我的尝试。 I realize that what I'm doing is not nesting the annotations under article like in JSON. 我意识到我正在做的事情不是像在JSON中那样将注释嵌套在文章下。 How can I do that? 我怎样才能做到这一点?

@article_attributes = create_prospective(scope: :article)
@annotation_attributes_valid = create_prospective(scope: :annotation)
@annotation_attributes_invalid = create_prospective(scope: :annotation, trait: :invalid)
post :create, {user: @user.id, article: @article_attributes, annotations: @annotation_attributes_valid }, format: :json

Note: create_prospective is a helper method for FactoryGirl 注意:create_prospective是FactoryGirl的辅助方法

Controller 控制者

def create
    @article = current_resource_owner.articles.build(article_params)

    if @article.save
      annotation_result = create_annotation(@article, params[:article][:annotations])

      render json: {article: @article, total_number_annotations: annotation_result[:total_count], number_annotations_succeeded: annotation_result[:success_count], number_annotations_failed: annotation_result[:failure_count], successful_annotations: annotation_result[:success_list], failed_annotations: annotation_result[:failure_list]}, status: annotation_result[:api_status]
      # end
    else
      render json: { errors: @article.errors }, status: 422
    end

end 结束

Note: create_annotation is a concern that saves the annotations, to be reusable in both the article controller and annotation controller 注意:create_annotation是一个保存注释的问题,以便可以在文章控制器和注释控制器中重复使用

Your specs are creating actual Article and Annotation objects instead of attribute hashes, and as you said, you haven't nested the Annotation inside the Article . 您的规范正在创建实际的ArticleAnnotation对象,而不是属性哈希,并且正如您所说的,您尚未将Annotation嵌套在Article The first thing you should do is create a parameter hash that you can verify has the same structure as your working JSON request. 您应该做的第一件事是创建一个参数哈希,您可以验证该哈希与工作的JSON请求具有相同的结构。 I'd expect that to look like this: 我希望它看起来像这样:

article_data = attributes_for(:article, annotations: [attributes_for(:annotation)])

Then, you should be able to post your attribute data properly to your controller: 然后,您应该能够将属性数据正确发布到控制器:

post :create, article: article_data, format: :json

Once you have the spec working, you can simplify your controller a bit by using accepts_nested_attributes_for on your Article model. 规范生效后,您可以通过在Article模型上使用accepts_nested_attributes_for来简化控制器。 Rails provides that for just this case, and it helps you validate all of your objects at once in case you don't want the Article to be created with invalid Annotation s, and it plays nicely with the way Rails does nested forms Rails仅在这种情况下提供了此功能,它可以帮助您一次验证所有对象,以防万一您不想使用无效的Annotation创建Article ,并且与Rails 嵌套表格的方式很好地结合在一起

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM