Ruby minitest uninitialized constant ::ActiveSupport (NameError) - ruby

I've got pure Ruby class which does the parsing of the JSON file to the expected hash (located in src/parsers/incoming_events/create_quiz.rb). I want to test this class with Minitest like below:
# test/src/parsers/incoming_events/create_quiz_test.rb
require 'minitest/autorun'
require_relative '../../../../src/parsers/incoming_events/create_quiz'
module Parsers
module IncomingEvents
class CreateQuiz < ActiveSupport::TestCase
test 'parse JSON to expected format' do
assert_equal expected_hash, service.call
end
private
def service
#service ||= ::Parsers::IncomingEvents::CreateQuiz.new(payload: payload)
end
def payload
{
'quiz' =>
{
'first_name' => 'john',
'last_name' => 'doe',
'ssn' => '1234',
}
}.to_json
end
def expected_hash
{ 'name': 'john doe' }
end
end
end
end
When I'm trying to run above code via ruby test/src/parsers/incoming_events/create_quiz_test.rb I'm getting below error:
test/src/parsers/incoming_events/create_quiz_test.rb:11:in `<module:IncomingEvents>': uninitialized constant Parsers::IncomingEvents::ActiveSupport (NameError)
from test/src/parsers/incoming_events/create_quiz_test.rb:10:in `<module:Parsers>'
from test/src/parsers/incoming_events/create_quiz_test.rb:9:in `<main>'

Related

Ruby stub 3 class inside minitest - NoMethodError: undefined method allow_any_instance_of

I want to test my pure Ruby lambda handler which looks like this:
def lambda_handler(event:, context:)
payload = Parsers::IncomingEvents.new(event: event).call
ln_response = LN::Api.new(payload: payload).create_quiz
Responses::CreateQuiz.new(ln_response: ln_response, event: event).call
{ statusCode: 200, body: { message: event }.to_json }
end
To do so I'm using below minitest test:
require 'pry'
require 'minitest/autorun'
require 'active_support'
require_relative '../../src/Quiz_create/app'
module QuizCreate
class HandlerTest < ActiveSupport::TestCase
test 'lambda_handler' do
allow_any_instance_of(Parsers::IncomingEvents::CreateQuiz).to receive(:call)
allow_any_instance_of(LexisNexis::Api).to receive(:call)
allow_any_instance_of(Parsers::Responses::CreateQuiz).to receive(:call)
assert_response :success, lambda_handler(event: event, context: '')
end
def event
File.read('events/event.json')
end
end
end
But instead of expected results I'm getting an error:
NoMethodError: undefined method `allow_any_instance_of' for #QuizCreate::HandlerTest:0x00007fe4d61268e0

NameError: uninitialized constant Parsers in RSpec

I'm trying to test simple class in my Ruby 2.5.0 app:
source/parsers/jira_parser.rb
module Parsers
class JiraParser
def initialize(event)
payload = event['body']
#event = JSON.parse(payload)
end
def call
{
reporter_email: reporter_email,
reporter_name: reporter_name,
ticket_number: ticket_number,
description: description
}
end
private
attr_reader :event
def reporter_email
event.dig('issue', 'fields', 'reporter', 'emailAddress')
end
# other methods from call are pretty much the same as `reporter_email`
With below specs:
spec/source/parsers/jira_parser_spec.rb
require 'spec_helper'
RSpec.describe Parsers::JiraParser do
describe 'call' do
subject(:hash_creation) { described_class.new(event).call }
let(:reporter_name) { 'john.doe' }
let(:reporter_email) { 'john.doe#example.com' }
let(:description) { 'This is a test description' }
let(:event) do
{
'body' => {
'issue': {
'key': 'TEST-Board-123',
'fields': {
'reporter': {
'displayName': reporter_name,
'emailAddress': reporter_email
},
'description': description
}
}
}
}
end
it { expect(hash_creation).to be_success }
end
end
But I've got an error:
NameError:
uninitialized constant Parsers
./spec/source/parsers/jira_parser_spec.rb:5:in `'
No examples found.
Should I add something to my rspec_helper to make it works?
Right now it's pretty basic:
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
end
I understand this is just Ruby, no Rails, hence there's no magic involved. You need to make a source file available in spec file, so you have to put on the top something like:
require_relative '../../../source/parsers/jira_parser
Hello I am still pretty new so this might help but I believe that you need to require JiraParser
require 'jira_parser'
require 'jira_parser/parser'
This might work but the error is because you are trying to use a parser that is not accessible in your current code.
Ok I figured out - all I had to do was to add -I source inside the .rspec file to will load all tested classes. So in my case .rspec will look like below:
.rspec
--require spec_helper
-I source

Standardizing api responses in a modular Sinatra application

I'm developing an api as a modular Sinatra web application and would like to standardize the responses that are returned without having to do so explicitly. I thought this could be achieved by using middleware but it fails in most scenarios. The below sample application is what I have so far.
config.ru
require 'sinatra/base'
require 'active_support'
require 'rack'
class Person
attr_reader :name, :surname
def initialize(name, surname)
#name, #surname = name, surname
end
end
class MyApp < Sinatra::Base
enable :dump_errors, :raise_errors
disable :show_exceptions
get('/string') do
"Hello World"
end
get('/hash') do
{"person" => { "name" => "john", "surname" => "smith" }}
end
get('/array') do
[1,2,3,4,5,6,7, "232323", '3245235']
end
get('/object') do
Person.new('simon', 'hernandez')
end
get('/error') do
raise 'Failure of some sort'
end
end
class ResponseMiddleware
def initialize(app)
#app = app
end
def call(env)
begin
status, headers, body = #app.call(env)
response = {'status' => 'success', 'data' => body}
format(status, headers, response)
rescue ::Exception => e
response = {'status' => 'error', 'message' => e.message}
format(500, {'Content-Type' => 'application/json'}, response)
end
end
def format(status, headers, response)
result = ActiveSupport::JSON.encode(response)
headers["Content-Length"] = result.length.to_s
[status, headers, result]
end
end
use ResponseMiddleware
run MyApp
Examples (in JSON):
/string
Expected: {"status":"success","data":"Hello World"}
Actual: {"status":"success","data":["Hello World"]}
/hash (works)
Expected: {"status":"success","data":{"person":{"name":"john","surname":"smith"}}}
Actual: {"status":"success","data":{"person":{"name":"john","surname":"smith"}}}
/array
Expected: {"status":"success","data": [1,2,3,4,5,6,7,"232323","3245235"]}
Actual: {"status":"error","message":"wrong number of arguments (7 for 1)"}
/object
Expected: {"status":"success","data":{"name":"simon","surname":"hernandez"}}
Actual: {"status":"success","data":[]}
/error (works)
Expected: {"status":"error","message":"Failure of some sort"}
Actual: {"status":"error","message":"Failure of some sort"}
If you execute the code, you will see that /hash and /error give back the required responses, but the rest do not. Ideally, I would not like to change anything in the MyApp class. It's currently being built on top of Sinatra 1.3.3, ActiveSupport 3.2.9 and Rack 1.4.1.
With some help from #sinatra on irc.freenode.org, I managed to get it down to what I want. I added the following to MyApp:
def route_eval
result = catch(:halt) { super }
throw :halt, {"result" => result}
end
I then changed the following line in ResponseMiddleware:
response = {'status' => 'success', 'data' => body}
to
response = {'status' => 'success', 'data' => body["result"]}
and all my test cases passed.

Unable to parse json with ruby

I have created the following class
class Contact
def initialize(id, name, phone)
#id = id
#name = name
#phone = phone
end
def to_json(*a)
{
json_class: self.class.name,
data: { id: #id, name: #name, phone: #phone }
}.to_json(*a)
end
def self.json_create(o)
new( o[:data][:id], o[:data][:name], o[:data][:phone] )
end
end
I can now convert it to json using this
Contact.new(1,'nik',10).to_json
=> "{\"json_class\":\"Contact\",\"data\":{\"id\":1,\"name\":\"nik\",\"phone\":10}}"
But it explodes with an error when I call JSON.parse on the it.
JSON.parse(Contact.new(1,'nik',10).to_json)
NoMethodError: undefined method `[]' for nil:NilClass
from (irb):44:in `json_create'
I picked up the syntax from this tutorial.
Get rid of the symbols in your json_create method.
def self.json_create(o)
new( o['data']['id'], o['data']['name'], o['data']['phone'] )
end
Use as_json instead of to_json.

Ruby: Thor and Httparty

I am trying to use HTTParty in my class FindXYZ extending Thor but it is not working. All I wish to do is use HTTParty get to query couchdb in my method xyz
When I try to run I see error cannot find get
require 'json'
require 'httparty'
require 'thor'
class FindXyz < Thor
include Thor::Actions
include HTTParty
headers 'Accept' => 'application/json'
server = '192.168.5.50:5984'
user = 'uname'
password = 'passo'
couchdb_url = "http://#{user}:#{password}##{server}"
basic_auth user, password
base_uri couchdb_url
default_params :output => 'json'
format :json
desc "xyz", "Find scenarios that contains SSL"
method_option :name, :aliases => "-t", :required => true
method_option :location, :aliases => "-s",:required => true
def xyz
name = options[:name]
loc = options[:location]
file_path = File.join(loc, name)
t_json = JSON.parse(File.read(file_path))
t_json["ids"].each do |temp|
path_to_doc = "/test123/#{temp}"
response = get(path_to_doc)
puts "Found => #{temp}" if response.to_s.include?('Birdy')
end #close the loop
end #close the method xyz
end #close class
Try it this way from outside the class
puts FindXyz.get('....').inspect
and HTTParty.get(...) inside FinXyz class

Resources