I have several Ruby methods that call methods from a library written in C++, via FFI gem. Some of the C++ methods involve spawning new threads inside a native library, others not.
The ruby methods look, basically, like this:
my_params = create_params_for_method1()
MyModule::method1(context, my_params) do |result|
puts "result is: #{result}"
end
All works fine.
A difficulty I have is that how to test these asyncronous methods? Some methods return value almost immediately and there's no issue with testing them:
expect { |b| MyModule.method1(my_context, my_params, &b) }.to yield_control
MyModule.method1(my_context, my_params) { |r| @result = r }
expect(@result).to eq "some_result123" # OK
But others keep sending data in a loop and therefore can't be tested in this way:
expect { |b| MyModule.method1(my_context, my_params, &b) }.to yield_control # error
MyModule.method1(my_context, my_params) { |r| @result = r } # error
expect(@result).to eq "some_result123" # @result is still nil
I could insert sleep N in a rspec test, but this be a sensible approach?
# expect { |b| MyModule.method1(my_context, my_params, &b) }.to yield_control
MyModule.method1(my_context, my_params) { |r| @result = r }
sleep 10
expect(@result).to eq "some_result123" # not nil, but...
How long in seconds should I N be so that it'll always pass? The more the better, but how long? How would I guess?
Also, it's a hack, isn't it? Also, in some cases it'll keep sending data from a native library multiple times. How would I make sure that I've received it all, in a test?
And a test isn't supposed to take a long, undetermenistic time to test a method, is it?
What's the approach in such a case?
Aucun commentaire:
Enregistrer un commentaire