Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`TypeMatcher` not working when used with `throwsA`

I have the following code in my app:

expect(() => dataSource.getLastPost(), throwsA(TypeMatcher<CacheException>()));

This results in the following error

Expected: throws <Instance of 'TypeMatcher<CacheException>'>
  Actual: <Closure: () => Future<PostModel>>
   Which: threw <Instance of 'CacheException'>

If I remove the TypeMatcher wrapping CacheException...

expect(() => dataSource.getLastPost(), throwsA(CacheException()));

then it still gives a similar error

Expected: throws <Instance of 'CacheException'>
  Actual: <Closure: () => Future<PostModel>>
   Which: threw <Instance of 'CacheException'>

I was wondering what I am doing wrong? Either way it's clear that we are expecting a CacheException and a CacheException is being thrown. Then why does the expect test not pass?

like image 870
Philip Avatar asked Dec 17 '22 14:12

Philip


1 Answers

It is correct to write throwsA(TypeMatcher<CacheException>())

The problem is you're likely facing is, in the context of Flutter and tests, there are two classes with the name TypeMatcher:

  • TypeMatcher from the package matcher, for tests
  • TypeMatcher from flutter/widgets, to navigate inside BuildContext.

They are both used the same way, aka TypeMatcher<SomeClass>. But only one of them is a Matcher, which tests understand.

Your problem being, you likely used TypeMatcher from flutter/widgets. And since it's not a matcher, then:

throwsA(TypeMatcher<MyClass>())

is interpreted as:

throwsA(equals(TypeMatcher<MyClass>())

The solution is to use the correct TypeMatcher, from package:matcher/matcher.dart.

But to begin with, you should not use TypeMatcher directly.

Instead of:

throwsA(TypeMatcher<MyClass>())

you should use the shorthand isA<T> matcher:

throwsA(isA<MyClass>())

This removes the name conflict entirely

like image 168
Rémi Rousselet Avatar answered Jan 11 '23 05:01

Rémi Rousselet