diff --git a/README.md b/README.md index c3ffd83..4dd8432 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186). -_1273 TILs and counting..._ +_1274 TILs and counting..._ --- @@ -852,6 +852,7 @@ _1273 TILs and counting..._ - [Skip Validations When Creating A Record](rails/skip-validations-when-creating-a-record.md) - [Specify New Attributes For #find_or_create_by](rails/specify-new-attributes-for-find-or-create-by.md) - [Temporarily Disable strong_params](rails/temporarily-disable-strong-params.md) +- [Test For A Subset Of Attributes On A Model](rails/test-for-a-subset-of-attributes-on-a-model.md) - [Test If An Instance Variable Was Assigned](rails/test-if-an-instance-variable-was-assigned.md) - [Test If deliver_later Is Called For A Mailer](rails/test-if-deliver-later-is-called-for-a-mailer.md) - [Test Out URL And Path Helpers In The Console](rails/test-out-url-and-path-helpers-in-the-console.md) diff --git a/rails/test-for-a-subset-of-attributes-on-a-model.md b/rails/test-for-a-subset-of-attributes-on-a-model.md new file mode 100644 index 0000000..f82b189 --- /dev/null +++ b/rails/test-for-a-subset-of-attributes-on-a-model.md @@ -0,0 +1,38 @@ +# Test For A Subset Of Attributes On A Model + +Let's say you are using RSpec to test some code that creates or updates an +ActiveRecord object. To evaluate that the code is working, you want to check +the value of a couple different attributes. Though you could have a series of +assert statements to check each value, you may want to combine them into a +single statement. + +```ruby +book = process_that_updates_book(params) + +expect(book.attributes).to match( + "title" => 'Updated title', + "publication_year" => 2001, + # ... you have to check *every* attribute +) +``` + +The `#match` matcher requires that every attribute in the hash matches. We +don't really care to check the `created_at`, `updated_at`, and other irrelevant +attributes. + +Instead, we can `match` on +[`hash_including`](https://rubydoc.info/gems/rspec-mocks/RSpec%2FMocks%2FArgumentMatchers:hash_including). +Additionally, we can `symbolize_keys` on the `attributes` to make the expected +data a little cleaner. + +```ruby +book = process_that_updates_book(params) + +expect(book.attributes).to match(hash_including( + title: 'Updated title', + publication_year: 2001, +)) +``` + +If the specified attributes match, then the expectation will pass. If at least +one of them doesn't, then it will fail. All other attributes are ignored.