Instance variable showing up as `nil` in rspec - ruby

I have the following test code:
require_relative '../spec_helper'
describe Chess::King do
before do
#piece = Chess::King.new('king1',:black)
#board = Chess::Board.new
end
describe '#possible_moves' do
context "placing king at location 4,5" do
#board.grid[4][5] = #piece
subject {#piece.possible_moves(#board)}
it {is_expected.to eq([3,5],[3,6],[4,6],[5,6],[5,5])}
end
end
end
Why am I getting this error:
in block (3 levels) in <top (required)>': undefined methodgrid' for nil:NilClass (NoMethodError)
I am not sure about this line: #board.grid[4][5] = #piece.
My intention here is to assign the piece object to the grid instance variable of board (8x8 array).

Try using let instead:
require_relative '../spec_helper'
describe Chess::King do
let(:piece) { Chess::King.new('king1',:black) }
let(:board) { Chess::Board.new }
describe '#possible_moves' do
context "placing king at location 4,5" do
before(:each) { board.grid[4][5] = piece }
subject {piece.possible_moves(board)}
it {is_expected.to eq([3,5],[3,6],[4,6],[5,6],[5,5])}
end
end
end

Related

undefined method 'execute' for nil:NilClass

I am making a tool in ruby which can interact with databases.
I am using amalgalite as an adapter for sqlite3.
Code:
require 'amalgalite'
# this is class RQuery
class RQuery
def db_open(db_name)
#db = Amalgalite::Database.new "#{db_name}.db"
make_class
end
def exec_this(query)
#db.execute(query)
end
def make_class
tables_list = exec_this("select name from sqlite_master where type='table'")
tables_list.each do |table|
#class_created = Object.const_set(table[0].capitalize, Class.new)
#class_created.class_eval do
define_singleton_method :first do
RQuery.new.exec_this("select * from #{table[0]} order by #{table[0]}.id ASC limit 1")
end
end
end
end
def eval_this(input)
instance_eval(input)
end
def code
print '>>'
input = gets
exit if input =~ /^q$/
puts eval_this(input)
code
end
end
Now when I am running the code everything works fine until I call table_name.first
It gives output
vbhv#fsociety ~/git/R-Query/bin $ ruby main.rb
Enter the code or q for quit
>>db_open('vbhv')
users
persons
people
programmers
>>Users.first
/home/vbhv/git/R-Query/lib/r-query.rb:36:in `instance_eval': undefined method `execute' for nil:NilClass (NoMethodError)
Did you mean? exec
from /home/vbhv/git/R-Query/lib/r-query.rb:29:in `block (3 levels) in make_class'
from (eval):1:in `eval_this'
from /home/vbhv/git/R-Query/lib/r-query.rb:36:in `instance_eval'
from /home/vbhv/git/R-Query/lib/r-query.rb:36:in `eval_this'
from /home/vbhv/git/R-Query/lib/r-query.rb:43:in `code'
from /home/vbhv/git/R-Query/lib/r-query.rb:44:in `code'
from /home/vbhv/git/R-Query/lib/r-query.rb:44:in `code'
from main.rb:4:in `<main>'
Now the 'execute' function it is talking about is inside amalgalite. What am I doing wrong here?? Thanks in Advance!
The problem in this was that the new class formed dynamically doesn't know about the connection variable '#db'. Hence the code solves the problem.
#class_created.instance_variable_set(:#database, #db)
A big thanks to Jagdeep Singh.

Rspec not finding class methods

I'm writing some tests for my backend jobs and I'm having a weird issue with rspec not finding my methods.
I wrote a simple class & test to illustrate the issue :
app/interactors/tmp_test.rb :
class TmpTest
def call
a = 10
b = 5
b.substract_two
return a + b
end
def substract_two
c = self - 2
return c
end
end
spec/interactors/tmp_test.rb :
require 'rails_helper'
describe TmpTest do
context 'when doing the substraction' do
it 'return the correct number' do
expect(described_class.call).to eq(13)
end
end
end
output:
TmpTest
when doing the substraction
return the correct number (FAILED - 1)
Failures:
1) TmpTest when doing the substraction return the correct number
Failure/Error: expect(described_class.call).to eq(13)
NoMethodError:
undefined method `call' for TmpTest:Class
# ./spec/interactors/tmp_test.rb:6:in `block (3 levels) in <top (required)>'
Finished in 0.00177 seconds (files took 1.93 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/interactors/tmp_test.rb:5 # TmpTest when doing the substraction return the correct number
It's not a class method, it's an instance method. Your test should look like this:
describe TmpTest do
subject(:instance) { described_class.new }
context 'when doing the subtraction' do
it 'returns the correct number' do
expect(instance.call).to eq(13)
end
end
end
This is a complete mess. Corrected version with comments:
class TmpTest
def call
a = 10
b = 5
# b.substract_two # why do you call method of this class on b?!
a + subtract_two(b)
end
def substract_two(from)
from - 2
end
end
Also: don’t use return in the very last line of the method.

How to check block is called using rspec

I want to check whether the block is called in my function using rspec. Below is my code:
class SP
def speak(options={},&block)
puts "speak called"
block.call()
rescue ZeroDivisionError => e
end
end
describe SP do
it "testing speak functionality can receive a block" do
sp = SP.new
def test_func
a = 1
end
sp_mock = double(sp)
expect(sp_mock).to receive(:speak).with(test_func)
sp.speak(test_func)
end
end
Below is my error:
SP testing speak functionality can receive a block
Failure/Error: block.call()
NoMethodError:
undefined method `call' for nil:NilClass
# ./test.rb:9:in `speak'
# ./test.rb:25:in `block (2 levels) in <top (required)>'
Could you please help. I spent lots of time in that.
You have to use one of RSpec's yield matcher:
describe SP do
it "testing speak functionality can receive a block" do
sp = SP.new
expect { |b| sp.speak(&b) }.to yield_control
end
end
I think Stefan provided the best answer. However I wanted to point out that you should be testing the behaviour of the code instead of implementation details.
describe SP do
it "testing speak functionality can receive a block" do
sp = SP.new
called = false
test_func = -> () { called = true }
sp.speak(&test_func)
expect(called).to eql(true)
end
end

How to call module in Ruby rspec?

lib/rspec/core/my_methods.rb
module MyLovelyModule
class My_methods
def my_lovely_method
save_world
config.to_prepare do
Dir.glob(Rails.root + "../simpleRspec/dummy_classes.rb").each do |c|
require_dependency(c)
end
end
end
end
end
lib/simpleRspec/dummy_classes.rb
describe MyLovelyModule do
class DummyClasses
before(:all) do
#dummy = DummyClasses.new
#dummy.extend MyLovelyModule
end
describe "MyLovelyModule" do
it "saves the world" do
expect {
#dummy.my_lovely_method
}.to raise_error MeltDownException
end
end
end
end
I got a error like that:-
C:/Users/afzala/RubymineProjects/simpleRspec/lib/simpleRspec/dummy_classes.rb:2:in `<top (required)>': uninitialized constant MyLovelyModule (NameError)
from -e:1:in `load'
from -e:1:in `<main>'
Process finished with exit code 1
could anyone please help me out for this issue
You need to load your module first. You also need to close the class before you define tests:
require 'lib/rspec/core/my_methods.rb'
describe MyLovelyModule do
class DummyClasses
end
before(:all) do
#dummy = DummyClasses.new
#dummy.extend MyLovelyModule
end
describe "MyLovelyModule" do
it "saves the world" do
expect {
#dummy.my_lovely_method
}.to raise_error MeltDownException
end
end
end
Also you will not be able to access #dummy in your test. You need to use before(:each) in place of before(:all)

wrong number of arguments ruby rspec

I'm trying to write unit tests for my code using rspec. I keep getting a "wrong number of arguments" error:
class MyClass
attr_accessor :env, :company,:size, :role, :number_of_hosts,:visability
def initialize(env, company, size, role, number_of_hosts, visability)
#env, #company, #size, #role, #number_of_hosts, #visability = env, company, size, role, number_of_hosts, visability
end
end
And here are my tests:
require_relative "../lib/MyClass.rb"
describe MyClass do
it "has an environment" do
MyClass.new("environment").env.should respond_to :env
end
it "has a company" do
MyClass.new("company").company.should respond_to :company
end
...
When I run rspec I get:
1) MyClass has an environment
Failure/Error: MyClass.new("environment").env.should respond_to :env
ArgumentError:
wrong number of arguments (1 for 6)
# ./lib/MyClass.rb:4:in `initialize'
# ./spec/MyClass_spec.rb:5:in `new'
# ./spec/MyClass_spec.rb:5:in `block (2 levels) in <top (required)>'
...
What am I missing?
EDIT
Sergio helped thanks...however
Sergio's answer worked...although I still have a further question:
Given the Class:
class Team
attr_accessor :name, :players
def initialize(name, players = [])
raise Exception unless players.is_a? Array
#name = name
raise Exception if #name && has_bad_name
#players = players
end
def has_bad_name
list_of_words = %w{crappy bad lousy}
list_of_words - #name.downcase.split(" ") != list_of_words
end
def favored?
#players.include? "George Clooney"
end
end
and spec...
require_relative "../lib/team.rb"
describe Team do
it "has a name" do
Team.new("random name").should respond_to :name
end
it "has a list of players" do
Team.new("random name").players.should be_kind_of Array
end
...
The tests pass without the same error...(This works fine: Team.new("random name"))
Any explanation?
Here is the error MyClass.new("environment"). As you have written def initialize(env, company, size, role, number_of_hosts, visability). So you should pass 6 parameters when you are calling MyClass#new method. But in practice you pass only one which is "environment". Thus you got the legitimate error - wrong number of arguments (1 for 6).

Resources