You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
The text was updated successfully, but these errors were encountered:
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:
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:
Works great for now, but not future-proof if Riot's internals change.
The text was updated successfully, but these errors were encountered: