Rspec checks are not performed randomly when parsing ActiveRecord objects generated by Mongoid events

I implemented a Mongoid-based activity logging mechanism that stores events in MongoDB.

The Mongoid model Activityhas events after_createthat perform different tasks depending on the type of activity being logged: (simplified example)

class Activity
  include Mongoid::Document

  after_create do |activity|
    method_name = "after_#{activity.event_type}"
    send(method_name) if respond_to? method_name
  end

  def after_user_did_something
    MyItem.create!(:type => :user_did_something)
  end
end

The test is as follows:

 it 'should hide previous [objects] create a new updated one' do
      2.times do 
        user.log_activity(:user_did_something) 
      end
      items = MyItems.where(:type => :user_did_something)
      items.count.should == 2
    end
 end

Sometimes tests end with items.countequal 0 instead of 2. This only happens when starting from the command line, rspec spec it never happens when starting only this test or when running all tests using Guard.

+4
source share
3

Mongodb . :

  • "" , .
  • Mongodb . , , , , , , , , .

, Mongoid, consistency: :strong, safe: true, .

+3

, - ( ), rspec expectations, :

 it 'should hide previous [objects] create a new updated one' do
  items = MyItems.where(:type => :user_did_something)

  expect { 2.times { user.log_activity(:user_did_something) } }.
  to change { items.count }.from(0).to(2)
end

[] ( , , ), rspec lazy-loading let, :

let(:items_count) { MyItems.where(:type => :user_did_something).count }

it 'should hide previous [objects] create a new updated one' do
  expect { 2.times { user.log_activity(:user_did_something) } }.
  to change { items_count }.from(0).to(2)
end
0

:

  • after_create
  • after_user_did_something
  • This object has MyItembeen created.

I suggest you break it down into several unit tests, each of which tests one thing. The added value that you get from this is that at least you will find out which part of the test really failed ...

class Activity
  include Mongoid::Document

  after_create { |activity| my_after_create_callback(activity.event_type) }

  def my_after_create_callback(activity_type)
    method_name = "after_#{activity_type}"
    send(method_name) if respond_to? method_name
  end

  def after_user_did_something
    MyItem.create!(:type => :user_did_something)
  end
end

it 'should call after_create' do
  expect_any_instance_of(Activity).to receive(:my_after_create_callback)
                                  .with(:user_did_something)

  user.log_activity(:type => :user_did_something)
end

it 'should call the correct after activity method' do
  expect_any_instance_of(Activity).to receive :after_user_did_something

  user.log_activity(:type => :user_did_something)
end

it 'should create new MyItem' do
  expect(MyItem).to receive(:create!).with(:type => :user_did_something)

  Activity.new.after_user_did_something
end
0
source

Source: https://habr.com/ru/post/1528933/


All Articles