Skip to content

Conversation

groyoh
Copy link
Contributor

@groyoh groyoh commented Jul 8, 2025

Context

byebug will not work properly within factory attribute or association definition:

FactoryBot.define do
   factory :subscription do
    customer do
      byebug # DOESN'T WORK
      create(:customer)
    end
  end

  factory :customer do
    after :create do |customer|
      byebug # WORKS
      create(:hubspot_customer, customer:)
    end
  end
end

The byebug call in the customer block will fail with the following error:

Failure/Error: byebug
     
     LoadError:
       cannot load such file -- /usr/local/bundle/gems/factory_bot-6.5.0/lib/factory_bot/core
     # /usr/local/bundle/gems/factory_bot-6.5.0/lib/factory_bot/evaluator.rb:43:in 'Kernel#require_relative'
     # /usr/local/bundle/gems/factory_bot-6.5.0/lib/factory_bot/evaluator.rb:43:in 'FactoryBot::Evaluator#method_missing'
     # /usr/local/bundle/gems/byebug-12.0.0/lib/byebug/attacher.rb:36:in 'Kernel#byebug'
     # ...
     # ./spec/spec_helper.rb:172:in 'block (2 levels) in <top (required)>'
     # /usr/local/bundle/gems/webmock-3.23.1/lib/webmock/rspec.rb:39:in 'block (2 levels) in <main>'

Using binding.pry instead will properly stop execution but it will not stop at the right stack level:

> lago exec api bundle exec rspec --color --format documentation spec/services/subscriptions/update_service_spec.rb
Subscriptions::UpdateService
  #call

From: /usr/local/bundle/gems/factory_bot-6.5.0/lib/factory_bot/evaluator.rb:42 FactoryBot::Evaluator#method_missing:

    38: def method_missing(method_name, ...)
    39:   if @instance.respond_to?(method_name)
    40:     @instance.send(method_name, ...)
    41:   else
  => 42:     SyntaxRunner.new.send(method_name, ...)
    43:   end
    44: end

Description

Using pry-byebug will solve the issue:

> lago exec api bundle exec rspec --color --format documentation spec/services/subscriptions/update_service_spec.rb
Subscriptions::UpdateService
  #call

From: /app/spec/factories/subscriptions.rb:13 :

    8: 
    9:     customer do
    10:       traits = []
    11:       traits << :with_hubspot_integration if with_hubspot_integration
    12:       binding.pry
 => 13:       create(:customer, *traits)
    14:     end
    15:     plan
    16:     organization { customer&.organization || plan&.organization || association(:organization) }
    17:     status { :active }
    18:     external_id { SecureRandom.uuid }

It also allows us to rely on features of both pry (show-source, cd, etc.) and byebug (continue, up, etc.) at the same time.

@groyoh groyoh merged commit fe34826 into main Jul 8, 2025
14 checks passed
@groyoh groyoh deleted the chore/pry-byebug branch July 8, 2025 12:08
diegocharles pushed a commit that referenced this pull request Jul 11, 2025
## Context

`byebug` will not work properly within factory attribute or association definition:

```ruby
FactoryBot.define do
   factory :subscription do
    customer do
      byebug # DOESN'T WORK
      create(:customer)
    end
  end

  factory :customer do
    after :create do |customer|
      byebug # WORKS
      create(:hubspot_customer, customer:)
    end
  end
end
```

The `byebug` call in the `customer` block will fail with the following error:

```shell
Failure/Error: byebug
     
     LoadError:
       cannot load such file -- /usr/local/bundle/gems/factory_bot-6.5.0/lib/factory_bot/core
     # /usr/local/bundle/gems/factory_bot-6.5.0/lib/factory_bot/evaluator.rb:43:in 'Kernel#require_relative'
     # /usr/local/bundle/gems/factory_bot-6.5.0/lib/factory_bot/evaluator.rb:43:in 'FactoryBot::Evaluator#method_missing'
     # /usr/local/bundle/gems/byebug-12.0.0/lib/byebug/attacher.rb:36:in 'Kernel#byebug'
     # ...
     # ./spec/spec_helper.rb:172:in 'block (2 levels) in <top (required)>'
     # /usr/local/bundle/gems/webmock-3.23.1/lib/webmock/rspec.rb:39:in 'block (2 levels) in <main>'
```

Using `binding.pry` instead will properly stop execution but it will not stop at the right stack level:

```shell
⋊> lago exec api bundle exec rspec --color --format documentation spec/services/subscriptions/update_service_spec.rb
Subscriptions::UpdateService
  #call

From: /usr/local/bundle/gems/factory_bot-6.5.0/lib/factory_bot/evaluator.rb:42 FactoryBot::Evaluator#method_missing:

    38: def method_missing(method_name, ...)
    39:   if @instance.respond_to?(method_name)
    40:     @instance.send(method_name, ...)
    41:   else
  => 42:     SyntaxRunner.new.send(method_name, ...)
    43:   end
    44: end
```

## Description

Using `pry-byebug` will solve the issue:

```shell
⋊> lago exec api bundle exec rspec --color --format documentation spec/services/subscriptions/update_service_spec.rb
Subscriptions::UpdateService
  #call

From: /app/spec/factories/subscriptions.rb:13 :

    8: 
    9:     customer do
    10:       traits = []
    11:       traits << :with_hubspot_integration if with_hubspot_integration
    12:       binding.pry
 => 13:       create(:customer, *traits)
    14:     end
    15:     plan
    16:     organization { customer&.organization || plan&.organization || association(:organization) }
    17:     status { :active }
    18:     external_id { SecureRandom.uuid }
```

It also allows us to rely on features of both `pry` (`show-source`, `cd`, etc.) and `byebug` (`continue`, `up`, etc.) at the same time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants