I have a method that that has a sorbet type signature definition. While trying to mock this method in tests using RSpec I get a type mismatch error. I'm trying to understand how I can resolve this issue and can add RSpec based tests without affecting sorbet type check.
sig {params(login_context: LoginContext, company_id: String).returns(T::Boolean)}
def populate_dummy_data(login_context, company_id)
Test Code:
@login_context = double(LoginContext, :requester => @requester) # Creates an instance of type Rspec::Mocks::double
Error:
expected no Exception, got #<TypeError: Parameter ‘login_context’: Expected type LoginContext, got type RSpec::Mocks::Double wit...a_populator_spec.rb:42
Mocha mocks (stub in tests) will not pass any type checks by default. This is deliberate and considered a feature; bare mocks make tests brittle and tend to cause problems when refactoring code, regardless of type checking.
When trying to test a method using a Mocha mock that fails a type check, we recommend rewriting the test to not use Mocha mocks. Either:
.stubs
to replace only certain methods.In the worst case, you can stub is_a?
to make a Mocha mock pass a type check, but please avoid doing this. It results in brittle tests and makes code harder to reason about. If you must:
# NOT RECOMMENDED!
fake_llama = stub
fake_llama.stubs(:llama_count).returns(17)
fake_llama.stubs(:is_a?).with(M::Llama).returns(true)
I'm not familiar with the differences between RSpec's mocks and Mocha's mocks (at Stripe where Sorbet is developed we use Mocha) but the principles should be the same.