Skip to content

force a setup to run last #39

@ghost

Description

This problem is unique to testing controllers. When testing a controller action/route, there is generally a request to be run. This request should, in my experience, always occur last, after any other setups. Because setups are run in order, it is not possible to do something like this:

context "GET show" do
  setup { get '/comments/123' }
  context "comment not found" do
    setup { mock(Comment).find('123') { nil } }
  end
end

The mocking takes place after the request, so the test doesn't work. Instead, I have to place the request in the nested context's setup block. However, this isn't a complete solution in itself. For example, if I had a further-nested context in which I want to do even more mocking, again, the request that I setup in the parent context is going to occur first. Depending on my needs I might have to go so far as to run the request within the assertion, which can be really repetitive if there are many assertions. I can DRY this up by making the request from a helper method, but it's still not as clean as it could be.

I tried to do this with context middleware, but it didn't work. I can get a setup block to run lastly for a context, but since that setup is inherited, the request runs multiple times within nested contexts, which is inefficient and also causes expectations to fail.

Essentially, for this to work, there needs to be a way to create a block that runs after setups, but is not actually part of any setup. Right now for my controllers I have this hack in a middleware that overrides a native Riot::Context method:

context.instance_eval do
  def runnables
    setups + after_setups +  @assertions + teardowns
  end
end

Works great for now, but not future-proof if Riot's internals change.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions