2

I am trying to do some rspec unit tests on a method in my model. The method returns a promise, and when resolved, the name of the person. The method is not the problem as I know that it works correctly. Here is my test code:

it 'should return correct name' do
  report = Report.new(first_name: 'Testy', last_name: 'Testerson')
  report.save!
  expect(report.name).to eql('Testy Testerson')
end

When I test it, I get the following error:

Failure/Error: expect(report.name).to eql('Testy Testerson')
TypeError:
  can't convert Promise to Array (Promise#to_ary gives Promise)

While debugging, I used the following line to inspect the returned value of the method:

puts report.name.inspect

And I got the following response:

#<Promise(70319926955580): "Testy Testerson">

The error seems to be happening because it tests the promise against the expected value. Why am I getting this error?

user3579220
  • 187
  • 1
  • 2
  • 9

2 Answers2

1

Using report.name.value fixes this issue

user3579220
  • 187
  • 1
  • 2
  • 9
1

When running code on the server, calls to store return a promise that is already resolved. But on the client the promise won't be resolved yet. Someone (forget the name atm) is working on adding support to promise directly into opal-rspec, but at the moment a returned promise won't wait for opal-rspec. The plan is once thats ready we'll add more tools to volt to make it easier for developers to test in both MRI and opal (like we do with Volt itself).

You can call .value on a promise to get back its value, but only if the promise has resolved. The safer way to do it is to use a .then block:

report.name.then do |name|
  expect(name).to eq('Bob')
end

Hopefully that helps.

Ryan
  • 956
  • 7
  • 8