Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stubbing of nested operations #32

Open
apotonick opened this issue Nov 22, 2018 · 8 comments
Open

Stubbing of nested operations #32

apotonick opened this issue Nov 22, 2018 · 8 comments
Milestone

Comments

@apotonick
Copy link
Member

Supposedly many people want to stub nested OPs/ACTs.

 expect(MyNestedOperation). to receive(:call).with("params" => {order_id: order.id, email: order.user.email)

We should explain how to do that in 2.1

@apotonick apotonick added this to the 2.1 milestone Nov 22, 2018
@fernandes
Copy link
Member

actually, I call the nested inside an step and stub MyNestedOperation.call is the better I can do atm hehehhe

@emaglio
Copy link
Member

emaglio commented Nov 23, 2018

I do
expect(MyNestedOperation).to receive(:call_with_circuit_interface).with(blabla).and_call_original which works fine.

The "real" problem is when you have a series of complex Nested operations and you simply want to test that separately so you simply want to stub a Nested operation and return a "usable" result object so instead to do and_call_original I want to say and_return(my_return_object).

I know that you can pass specific params to make that fail but it would be just quicker/easier if you can simply stub it and also the spec could be a bit cleaner focusing on the actual operation under testing.

Hope it makes sense

@fernandes
Copy link
Member

it's so rspec hehehe I prefer the purity (and rubity) of minitest heheh but it's good to learn your technique, can be useful try to make something on minitest, thanks for sharing

@brindu
Copy link

brindu commented Nov 23, 2018

@emaglio do you have a way to create a "usable" result object ? As you said this is a problem 😅 When I try something naive it doesn't work (without surprise...) :

describe 'Nested activity' do
  class A < Trailblazer::Operation
    step ->(ctx, **) { p 'nested test' }
  end

  class B < Trailblazer::Operation
    step ->(ctx, **) { p 'test' }
    step Nested(A)
  end
                                                                                                                                                                                                              it 'can be stubbed' do
    end_event = Trailblazer::Operation::Railway::End::Success.new(semantic: :success)
    result_object = [end_event, [{}, {}]]
    expect(A).to receive(:call_with_circuit_interface).and_(result_object)

    B.call
  end
end

@apotonick
Copy link
Member Author

You mean "usable" in terms of what to do with the return values on the circuit interface level, @brindu ?

@emaglio
Copy link
Member

emaglio commented Nov 24, 2018

@apotonick “usable” in order to write a test like (I’m with the phone, hard to write code):

  • if the Nested op returns this signal and this ctx I’ll have this result

Makes sense?

@brindu maybe I have used the wrong word for that, I don’t see it a “problem” but it would be good to have the possibility to do it and no sorry I haven’t tried to return a result object yet.

Since the complexity of the result objects maybe we should think to expose some higher level API to return a “fake” object, maybe in TRB-test or TRB-story? @apotonick

@brindu
Copy link

brindu commented Nov 24, 2018

“usable” in order to write a test like (I’m with the phone, hard to write code):

* if the Nested op returns this signal and this ctx I’ll have this result

This is exactly what I want to do ! For example to isolate the tests from a higher level operation/activity which acts like an orchestrator depending on nested operations result.

@panSarin
Copy link
Collaborator

panSarin commented Nov 29, 2018

Just to be sure, below example won't work in 2.0 , but will work in 2.1 yup ?

Admin::Staff::Operation::Create does not implement: call_with_circuit_interface

when i try to

expect(Admin::Staff::Operation::Create).to(
        receive(:call_with_circuit_interface)
        .and_return(instance_double(Trailblazer::Operation::Result, success?: true))
      )

And that is how my code where i try to call for nested operation looks like:

step Nested(:get_source_operation!, input: ->(options) do
          {
              "params" => options["params"]
          }
        end)

 def get_source_operation!(options, staff:, **)
          if staff.present?
            Admin::Staff::Operation::Create
          else
            Admin::Staff::Operation::InvitationSend
          end
        end

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

No branches or pull requests

5 participants