Coder Social home page Coder Social logo

Comments (17)

unorthodoxgeek avatar unorthodoxgeek commented on May 30, 2024 3

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.

unorthodoxgeek avatar unorthodoxgeek commented on May 30, 2024 1

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.

dblock avatar dblock commented on May 30, 2024

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.

rboyd avatar rboyd commented on May 30, 2024

looks pretty similar to what I've got

from grape.

jonhyman avatar jonhyman commented on May 30, 2024

Has anyone written spec tests for Grape helpers?

from grape.

dblock avatar dblock commented on May 30, 2024

@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.

dblock avatar dblock commented on May 30, 2024

I added a section in #56 about how to write a test with rspec. I'm going to close this.

from grape.

jonhyman avatar jonhyman commented on May 30, 2024

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.

dblock avatar dblock commented on May 30, 2024

@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.

jonhyman avatar jonhyman commented on May 30, 2024

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.

dblock avatar dblock commented on May 30, 2024

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.

jonhyman avatar jonhyman commented on May 30, 2024

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.

dblock avatar dblock commented on May 30, 2024

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.

dblock avatar dblock commented on May 30, 2024

@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.

unorthodoxgeek avatar unorthodoxgeek commented on May 30, 2024

@dblock sorry dude, will do.

from grape.

dblock avatar dblock commented on May 30, 2024

@unorthodoxgeek no worries ;)

from grape.

9mm avatar 9mm commented on May 30, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.