Git Product home page Git Product logo

Comments (11)

jessieay avatar jessieay commented on August 18, 2024

๐Ÿ‘ second example looks obviously better.

I guess an alternative would be a PR to shoulda that makes this obsolete

from guides.

gylaz avatar gylaz commented on August 18, 2024

I was under the impression that the second example wouldn't work for uniqueness due to shoulda-matchers not creating a record before trying to see if another can be created. If however, the second example just works, then I'm ๐Ÿ‘ on this.

from guides.

jessieay avatar jessieay commented on August 18, 2024

@gylaz the reason that the second example works, at least as far as I understand, is that otherwise shoulda uses an implicit subject of Object.new.

In that case, shoulda is not smart enough to use valid attributes for the object, whereas FG.build is. But I could be wrong on that...

from guides.

jferris avatar jferris commented on August 18, 2024

Neither of these examples is using an explicit subject. By "explicit subject" the guideline means literally using the method subject within an it block:

describe "#author_name" do
  let(:author) { User.new(name: "Billy") }
  subject { Post.new(author: author) }

  it "returns its author name" do
    expect(subject.author_name).to eq(author.name)
  end
end

The idea is that "subject" is only useful if it's so obvious which object you're talking about that you don't need to call out the subject. If you need to reference it explicitly, you can use a name instead. If you're using is_expected_to, you're using subject as intended.

The change linked to for #133 was about should vs is_expected_to. If you replace the method is_expected_to with should, you're following the guideline in both of your examples. This was simply a preference for one alias over another, as we generally found should to be more readable.

Re: validates_uniqueness_of - I thought you would have to create the registration and not build it, so that shoulda could properly attempt a save with an existing attribute value. I don't think that's related to the explicit subject guideline, though.

from guides.

jessieay avatar jessieay commented on August 18, 2024

@jferris I am not sure why Grayson's example with the subject { build(:registration) } works for the validates_uniqueness_of matcher...but it does.

@Graysonwright do you have more insight into why including the subject inside the describe block fixed the shoulda issue with `validates_uniqueness_of`` that occurs without a subject?

from guides.

c-lliope avatar c-lliope commented on August 18, 2024

Ah, thanks @jferris โ€“ I misunderstood.

I had assumed that "explicit subject" referred to defining the subject explicitly, not to using it explicitly. That makes a lot more sense now. To confirm, we should be using this syntax, then?

  describe "Validations" do
    subject { build(:registration) }

    it { should validate_presence_of(:email) }
    it { should validate_presence_of(:mobile_phone_number) }
    it { should validate_uniqueness_of(:email) }
    it { should validate_uniqueness_of(:mobile_phone_number) }
  end

from guides.

c-lliope avatar c-lliope commented on August 18, 2024

It looks like validate_uniqueness_of now uses the subject as the original record, and saves it in the database. It then creates a new object using subject.class.new and validates the uniqueness of that one.

See https://github.com/thoughtbot/shoulda-matchers/pull/567/files#diff-d732d58560615deb1ccbca127d2ba736R208

from guides.

jferris avatar jferris commented on August 18, 2024

To confirm, we should be using this syntax, then?

Yes, that looks correct to me.

It looks like validate_uniqueness_of now uses the subject as the original record, and saves it in the database.

Cool; that it explains why build works now.

from guides.

jessieay avatar jessieay commented on August 18, 2024

@Graysonwright are you going to open a PR for this? Would be good to have a comment explaining next steps :)

from guides.

TorvaldsDB avatar TorvaldsDB commented on August 18, 2024
require 'rails_helper'

RSpec.describe Score, type: :model do
  let(:score) { build(:score) }
  subject { described_class }

  it { is_expected.to validate_numericality_of(:score) }

  it 'belongs to staff' do
    assoc = subject.reflect_on_association(:staff)

    expect(assoc.macro).to eq :belongs_to
  end
end

This is my codes, but I occurred the issues, looks like this:

ยป rspec spec/models/score_spec.rb                                                                                                                             [ruby-2.5.1][19:04:09]
F

Failures:

  1) Score should validate that :score looks like a number
     Failure/Error: it { is_expected.to validate_numericality_of(:score) }

     Shoulda::Matchers::ActiveModel::AllowValueMatcher::AttributeDoesNotExistError:
       The matcher attempted to set :score on the Class to "abcd", but that
       attribute does not exist.

my Score looks like this:

class Score < ApplicationRecord
  belongs_to :staff

  validates :score, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 5 }
end

why? and Thank you very much.

from guides.

jessieay avatar jessieay commented on August 18, 2024

@TorvaldsDB when you set subject { described_class } that is for the Score class , but you should always test validations on an instance of a class. So if you change that to subject { described_class.new } it should pass or give you a different error at least.

In Grayson's example above, he sets subject { build(:registration) } - this is shorthand for subject { FactoryBot.build(:registration) }, which is creating an instance of the Registration class.

We frequently use FactoryBot (https://github.com/thoughtbot/factory_bot) in test suits to easily create objects for tests. You might consider giving it a try.

from guides.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.