Comments (17)
seriously? testing helper methods in a ruby library doesn't seem CRITICAL to you? In what universe does this ever make sense?!
This is a HUGE flaw in this library, and you just find it fit to simply close the issue and say "hey, I don't like testing stuff, so this ain't getting fixed", this is Ruby, we do everything TDD, and you just think it's logical just to ignore that?
Fixing this shouldn't be horribly hard, instead of doing that god awful complicated crap you're doing, simply apply the methods on something which can be easily accessed and thus, stubbed. The API class should have a helper method which points to the helper module. It's as simple as that.
from grape.
just to elaborate, I have a helper method called current_user, I want to simulate a situation where the user is logged in, thus, current_user isn't nil.
I just have absolutely no way of doing someting.stub(:current_user).and_return(user) to do that. This makes testing the logged in scenario impossible. And thus, writing using this otherwise nice library, impossible, because I won't write untested code...
from grape.
This is what I have working as a request spec in spec/requests/api_v1.rb. There's got to be a better way :)
require 'spec_helper'
describe Api_v1 do
describe "GET /api/v1/widgets/:slug" do
it "returns a widget represented by slug" do
@widget = Fabricate(:widget)
get "/api/v1/widgets/" + @widget.slug
response.body.should == MultiJson.encode(@widget.serializable_hash)
end
end
end
from grape.
looks pretty similar to what I've got
from grape.
Has anyone written spec tests for Grape helpers?
from grape.
@johnyman: i tried to do it but couldn't figure out anything nice - instead I made helpers thin wrappers calling another module (eg. api_cache_helper calls api_cache) and wrote tests for the module.
from grape.
I added a section in #56 about how to write a test with rspec. I'm going to close this.
from grape.
Daniel, any idea how to ensure that a helper method was called from an endpoint? I'm testing my helpers in a similar way you're describing, but I have a hard time testing that get('/api/v1/foo')
actually calls helper method bar
. Without this, I have a hard time doing good integration testing without repeating myself.
from grape.
@johnyman: did you try stubbing the module method or using the regular rspec stuff that counts calls? afterall this is just a module
from grape.
The problem is which module ends up getting stubbed? I've tried doing everything from MyApi.should_receive(:bar) to Object.any_instance.should_receive(:bar) to no avail. If you set a breakpoint in the test and run
Object.descendants.select{|o| o.instance_methods.include?(:bar)}
What you'll get are all dynamic classes. This makes setting up the expectation pretty tricky.
from grape.
Ok. So I don't know the answer to this. The helpers get mounted and you can no longer stub them.
I think testing the fact that a helper is called is the same as stubbing in testing a controller. It's something I personally dislike in suggested rails testing practices. The important part of an API is to avoid regressions, ie. behave the same externally. So if the helper does something meaningful, it should have an impact either on the result or on the system. For example, I have an authenticated
helper - so I make sure my APIs return 401 unless the user is logged in. I also have a logger
helper, so I make sure it logged an entry to the database on every call. Etc. What does knowing that the helper is called actually test?
from grape.
I have more than one route which calls the same helper which does a nontrivial amount of work. The simplest example that is close to what I'm doing is: you have two routes both return {:status => some_helper}
as part of the response payload, and that some_helper
can return one of 5 status messages based on different conditions. My goal is to make sure that neither one of these routes regress. I also want to avoid duplicating tests for these two routes by adding the 5 tests to the helper and then ensuring that the routes call the helper. This also seems suboptimal, it's somewhat of a "house of cards" test suite, I agree with you there.
How would you go about testing something like that? This logic doesn't belong in the model; it's specific to a version of the API.
from grape.
I'd copy paste the crap out of tests :)
You can generate tests too if it feels like you're repeating yourself, if your input is X and your expected result is a 403 error and if given "Z" it's 200:
{ "X" => 403, "Z" => 200 }.each_pair { |input, output|
it "given #{input} should produce #{output}" do
get "/api/v1/method/name?q=#{input}"
response.status.should == output
end
}
Replace the status code with the invocation of the helper. And if you need to eval in the context of the test, replace by a string and call instance_eval(output).
For a longer discussion, we can take it offline dblock[at]dblock[dot]org - I am very interested in this since I am giving a talk on Grape at NYC.rb next week.
from grape.
@unorthodoxgeek First, I opened the issue 2 years ago and the issue title was "How do I write a spec test for an API method provided by Grape?" An example was added to README and I closed the issue.
There was a discussion on helpers. You do make a very good point, so you should feel free to open a new issue that says exactly what you're saying.
from grape.
@dblock sorry dude, will do.
from grape.
@unorthodoxgeek no worries ;)
from grape.
Can someone assist me with this? http://stackoverflow.com/questions/16799944/sending-data-in-post-request-application-xml-in-integration-test
All the examples are for simple get requests
from grape.
Related Issues (20)
- Param with multiple acceptable Hash Types HOT 4
- Define contract instead of params HOT 8
- undefined method `rewind' for #<Rack::Lint::Wrapper::InputWrapper w/Rack >= 3.0 HOT 4
- custom type not suppot multiple types, raise `Grape::Exceptions::ValidationErrors` HOT 1
- Route#options and Route#settings are confusing HOT 1
- Ruby 3.3 && cookiejar = ArgumentError HOT 1
- Use Rack's HeadersHash instead of {}
- endpoint method_missing vs override inspect HOT 2
- Values Validator => Proc's arity < 2 ? HOT 3
- Rails Edge requires Ruby >= 3.1
- Fix specs for Rack Edge
- Fix `params` warning method redefined
- Better tracking of gems deprecation
- Rack::Lint::Error => a header value must be a String or Array of Strings, but the value of 'content-type' is a NilClass HOT 2
- Recognize_path should account for HTTP method HOT 1
- Grape and Protecting Against Mass Assignment Abuse HOT 8
- Why do you convert PATH_INFO? Is there some RFC? HOT 2
- Add support for exclusive parameter groups (e.g. exactly_one_of) HOT 2
- Drop support rack ~> 1 ? HOT 2
- Replace Appraisals by eval_gemfile ? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from grape.