简体   繁体   中英

Rspec model methods return nil when created by let

Ok, so this may seem like a total newbie ask, but when I create an instance of my model with let , for some reason all of the getter methods on it return nil. Here's my example:

Model:

class Parcel < ActiveRecord::Base
  extend UUIDHelper

  serialize :address, ActiveRecord::Coders::Hstore

  self.rgeo_factory_generator = RGeo::Geographic.spherical_factory srid: 3785

  attr_accessible :address, :area_poly, :id, :lonlat, :municipal_id
end

Spec:

require 'spec_helper'
require 'street_address'

describe Parcel do
  let(:geo_factory) { RGeo::Geographic.spherical_factory(srid: 3785)}
  let(:point1) {geo_factory.point(-72.9229165, 41.3096987)}
  let(:point2) {geo_factory.point(-72.9229169, 41.3096987)}
  let(:point3) {geo_factory.point(-72.9229169, 41.3096983)}
  let(:point4) {geo_factory.point(-72.9229165, 41.3096983)}
  let(:line_string) {geo_factory.line_string([point1,point2,point3,point4])}
  let(:polygon) {geo_factory.polygon(line_string)}
  let(:parcel) { Parcel.create(
      municipal_id: 'abc123',
      area_poly: polygon,
      #lonlat: polygon.centroid,
      address: StreetAddress::US.parse('55 Whitney Ave New Haven, CT 06510').as_json
  )}

  it "#municipal_id should not be nil" do
    parcel.municipal_id.nil? should_not be_true
  end
end

(the #longlat attribute is commented out because calling the .centroid method on a spherically defined polygon in RGeo is a no-no. Getting the right projection, while on my list of to-dos, is not relevant to this question) And the spec fails like so:

expected: non-true value
  got: #<Parcel id: nil, municipal_id: nil, address: {}, created_at: nil, updated_at: nil, area_poly: nil, lonlat: nil>

FWIW, here's the Rspec log:

Connecting to database specified by database.yml
   (0.1ms)  BEGIN
   (7.2ms)  SELECT * FROM geometry_columns WHERE f_table_name='parcels'
   (0.1ms)  SAVEPOINT active_record_1
  SQL (4.2ms)  INSERT INTO "parcels" ("address", "area_poly", "created_at", "id", "lonlat",     "municipal_id", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7)  [["address", "\"number\"=>\"55\",\"street\"=>\"Whitney\",\"street_type\"=>\"Ave\",\"unit\"=>NULL,\"unit_prefix\"=>NULL,\"suffix\"=>NULL,\"prefix\"=>NULL,\"city\"=>\"New Haven\",\"state\"=>\"CT\",\"postal_code\"=>\"06510\",\"postal_code_ext\"=>NULL"], ["area_poly", #<RGeo::Geographic::SphericalPolygonImpl:0x80b773e0 "POLYGON ((-72.9229165 41.3096987, -72.9229169 41.3096987, -72.9229169 41.3096983, -72.9229165 41.3096983, -72.9229165 41.3096987))">], ["created_at", Mon, 02 Jun 2014 11:59:51 UTC +00:00], ["id", nil], ["lonlat", nil], ["municipal_id", "abc123"], ["updated_at", Mon, 02 Jun 2014 11:59:51 UTC +00:00]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
   (0.1ms)  ROLLBACK

For reference, I can successfully run Parcel.create in a Rails console, and get instance variables to return non-nil values

I'm running rails 3.2, using postgres 9.3 with postgis 2, and heavily relying on activerecord-postgis-adaptor, RGeo, activerecord-postgres-hstore, among other gems.

Any thoughts?

You're missing a period. should_not is intended to be sent to the object whose value you are checking, as in:

parcel.municipal_id.nil?.should_not be_true

Because it's monkey patched on all objects, though, you were invoking it on RSpec's subject and passing the result (a Proc ) as a block to nil? , which is ignoring it. The error message reflects that the object being evaluated is the subject Parcel instance.

As an aside, note that the current and preferred syntax for this in RSpec is:

expect(parcel.municipal_id.nil?).to_not be_truthy  # be_true was renamed to be_truthy in RSpec 3

or if you really want to only check for a value of true :

expect(parcel.municipal_id.nil?).to_not be(true)

or if you want more compactness:

expect(parcel.municipal_id).to_not be_nil

or if you prefer the Shakespearean feel:

expect(parcel.municipal_id).to be

or if you want to take advantage of its , which was factored out into a separate gem as of RSpec 3, then you can replace the entire it call with:

its(:municipal_id) { should_not be_nil }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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