Skip to content

Instantly share code, notes, and snippets.

@tejasbubane
Created March 26, 2019 15:28
Show Gist options
  • Save tejasbubane/897712413c38fd57a3c516c6fae8e13f to your computer and use it in GitHub Desktop.
Save tejasbubane/897712413c38fd57a3c516c6fae8e13f to your computer and use it in GitHub Desktop.
Testing with_lock activerecord
# For stackoverflow question: https://stackoverflow.com/questions/55339129/how-to-test-lock-mechanism
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
# Activate the gem you are reporting the issue against.
gem "activerecord", "5.2.0"
gem "sqlite3", "~> 1.3.6"
gem "rspec"
end
require "active_record"
require "logger"
require "rspec"
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :bank_accounts, force: true do |t|
end
create_table :transactions, force: true do |t|
end
create_table :bank_account_transactions, force: true do |t|
t.integer :bank_account_id
t.integer :bank_transaction_id
end
end
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
class BankAccount < ApplicationRecord; end
class Transaction < ApplicationRecord; end
class BankAccountTransaction < ApplicationRecord
belongs_to :bank_account
belongs_to :bank_transaction, class_name: "Transaction"
end
class ImportService
def import_transactions(bank_account, transactions)
bank_account.with_lock do
transactions.each do |transaction|
import(bank_account, transaction)
end
end
end
private
def import(bank_account, transaction)
BankAccountTransaction.create!(bank_account: bank_account,
bank_transaction: transaction)
end
end
RSpec.describe "BankAccount" do
subject { BankAccount.new }
let(:transactions) do
# create 2 dummy transactions to pass to import method
[Transaction.create!, Transaction.create!]
end
describe "#import_transactions" do
it "runs with lock" do
# Test if with_lock is getting called
expect(subject).to receive(:with_lock) do |*_args, &block|
# block is provided to with_lock method
# execute the block and test if it creates transactions
expect { block.call }
.to change { BankAccountTransaction.count }.from(0).to(2)
end
ImportService.new.import_transactions(subject, transactions)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment