jasmine - how to check if an argument exists? - jasmine

good day.
im testing to see function got all her args.
i know what value two of her args must have,
but for the third arg, i just want to test if it exists.
expect(myFunction).toHaveBeenCalledWithMatcher({
a: 1,
b: 2,
c: dont know its val but want it to exist
});
thanks in advance

You can also use jasmine.any. In case you expect a number it could be:
expect(myFunction).toHaveBeenCalledWith({
a: 1,
b: 2,
c: jasmine.any(Number)
});
It is also possible jasmine.any(Function) and so on. From Jasmine doc:
jasmine.any takes a constructor or “class” name as an expected value. It returns true if the constructor matches the constructor of the actual value.

Try
expect(myFunction.mostRecentCall.args[2]).toBeDefined();
and leave out the argument in the toHaveBeenCalledWith test.

Related

Rspec expect with object validate values

I am doing tests and I want to assert that an object that goes to a dependency contains the values I am expecing. For this I have the next piece of code:
foo = Foo.new(1, 10, 0)
dependency = double
expect(dependency).to receive(:function).with(foo)
But this fails, obviously, as in the code I do a Foo.new ... so this object is not the same as the one in the logic. It makes sense, and I get an error like the next:
#<Double (anonymous)> received :function with unexpected arguments
expected: (#<Foo:0x00000000001 #value_1=1, #value_2=10, #value_3=0>)
got: (#<Foo:0x00000000002 #value_1=1, #value_2=10, #value_3=0>)
But the values on the object are the same.
Is there any way of validating only the values and not the object itself?
I can do the following, and it works, but this scenario has just three properties. On a bigger object, this will be a bit of a mess.
expect(dependency).to receive(:function).with(having_attributes(value_1: 1, value_2: 10, value_3: 0)
can this validation be done out of the box?
Thanks.
EDIT1: This is the code that I am trying to test
foo = Foo.new(value_1, value_2, value_3)
#dependency.function(foo)

How to make Ruby Mocha mock only check about one parameter

I want to mock this function:
def self.set_segment_info(segment_info, history_record)
history_record.segment_info = segment_info
end
In my test, I want a mock that only confirms that I called set_segment_info with an expected value. I don't care about what I pass in for history_record.
How would I do this? I tried
SegmentHistoryRecord.expects(:set_segment_info).with(:segment_info => expected_segment_info, :history_record => anything)
But that doesn't work.
I ran into this today and ended up doing something like:
SegmentHistoryRecord.expects(:set_segment_info).with(
expected_segment_info,
anything
)
I find it more readable that the do version and it helped me avoid a rubocop issue with too many parameters.
Here's an implementation where, if your function takes a lot of parameters, it's more convenient to specify a value for just the one you care about, instead of for all of them:
expected_segment_info = # ...
SegmentHistoryRecord.expects(:set_segment_info).with() { |actual_parameters| actual_parameters[:segment_info] == expected_segment_info }
(Where, as in the original question, set_segment_info is the function being mocked, and segment_info is the parameter whose value you want to match. Note that the history_record parameter -- and any others that might be present -- don't need to be included.)
SegmentHistoryRecord.expects(:set_segment_info).with() do |param1, param2|
# change below to your verification for :segment_info
# and leave param2 doing nothing, the expectation will ignore param2
param1 == expected_segment_info
end

Check whether an array contains some data

I have 2 variables, users and friend inside a component
Variable users is an array. Each iteration contains id, name and email
Variable friend have same structure in addition to pivot.
In my components file (.vue file), I need to check whether users contains friend without using loops so that I can use it inside the v-if condition.
Note: email and id are unique values.
How can I check it? Single line code will be very helpful.
Eg:
users have 2 iterations
id: 1
name: First
email: first#example.com
id: 2
name: Second
email: second#example.com
friend is like this
id: 2
name: Second
email: second#example.com
pivot: {...}
Use _.find() lodash function
_.find(users, {id: friend.id});
The first parameter is the array which you want to check and the second is the condition to satisfy. Remember this will return the specific iteration of the array instead of true or false but you can use it as a condition. If it returns null then it will take it as false, if there is something then it will be taken as true.
Try using v-if:
<div v-if=":user.friend"></div>

RSpec - trying to stub a method that returns its own argument

I have a method which I'm trying to stub out in my unit test. The real method gets called with one argument (a string) and then sends out a text message. I need to stub out the method but return the string that gets passed in as an argument.
The code I have in my RSpec test is this:
allow(taxi_driver).to receive(:send_text).with(:string).and_return(string)
This returns:
NameError: undefined local variable or method 'string'
If I change the return argument to :string, I get the following error:
Please stub a default value first if message might be received with other args as well
I've tried googling and checking the relishapp.com site, but can't find the answer to something which appears quite simple and straightforward.
You can pass a block:
allow(taxi_driver).to receive(:send_text).with(kind_of(String)){|string| string }
expect(taxi_driver.send_text("123")).to eq("123")
My method is being called like this: send_text("the time now is #{Time.now}"). The string varies according to the time, thats why I need the mock to return the varying string. Perhaps its not within the scope of a mock to do this?
In such a case, I usually use Timecop gem in order to freeze system time. Here is a sample use case:
describe "#send_text" do
let(:taxi_driver) { TaxiDriver.new }
before do
Timecop.freeze(Time.local(2016, 1, 30, 12, 0, 0))
end
after do
Timecop.return
end
example do
expect(taxi_driver.send_text("the time now is #{Time.now}")).to eq \
"the time now is 2016-01-30 12:00:00 +0900"
end
end

How to access a property of an array in Ruby

I have this object of class Array
>> answers_to_problem
=> [#<Answer id: 807, problem_id: 1, player_id: 53, code: "function y = times2(x
)\r\n y = 2*x;\r\nend", message: nil, score: 12, output: nil, hide: nil, create
d_at: "2010-02-02 11:06:49", updated_at: "2010-02-02 11:06:49", correct_answer:
nil, leader: nil, success: true, cloned_from: nil>]
For doing a binary check, I need access to the success field. I am not sure I am even using the right terminology here so I can not search how to access it.
answer_to_problems was found this way:
answers_to_problem = Answer.find_all_by_problem_id_and_player_id(current_problem,player_id)
Ultimately, I want to do this check:
is_correct = (answers_to_problem.success == true)
That isn't a property of the array — it's a property of the object in the array. So you'd so answers_to_problem[0].success to access the success attribute of the first object of the array.
Are you sure, you want to use find_all? If you know you'll only get one Answer back, you should use find without the all. That way you get a single Answer object instead of an array.
If you can get back more than one answer, do you want to check that all the answers are successful or just that one of them is?
You can do the former with: answers.all?(&:success) and the latter with answers.any?(&:success).
A bit outside the question here, but:
is_correct = (answer_to_problem.success == true)
Here you are doing an assignment and a truth check which are not really needed.
is_correct is here just reflecting whatever answer_to_problem.success would be. Shorten:
answer_to_problem.success == true
Now you're still performing a comparison to get a boolean value which you already have. Shorten:
answer_to_problem.success
There is a statement which you can use in the same manner you'd use is_correct. To make it read even better you could do:
class Answer
def correct?
success
end
end
And just use answer_to_problem.correct?

Resources