Have this abstract class to get data from remote data source
abstract class NumberTriviaRemoteDataSource {
/// Calls the http://numberapi.com/{number} endpoint.
///
/// Throws a [ServerException] for all error code
Future<NumberTriviaModel> getConcreteNumberTrivia(int number);
}
and have this abstract class for repository in domain layer
abstract class NumberTriviaRepository {
Future<Either<Failure, NumberTrivia>> getConcreteNumberTrivia(int number);
}
bellow I created a test to implement NumberTriviaRepository
class
@GenerateMocks([NumberTriviaRemoteDataSource])
void main() {
late final NumberTriviaRepositoryImpl repository;
late final MockNumberTriviaRemoteDataSource mockRemoteDataSource;
setUp(() {
mockRemoteDataSource = MockNumberTriviaRemoteDataSource();
repository = NumberTriviaRepositoryImpl(
numberTriviaRemoteDataSource: mockRemoteDataSource,
);
});
group('getConcreteNumberTrivia', () {
//to make test manageable create variables
const tNumber = 1;
const tNumberTriviaModel =
NumberTriviaModel(text: 'test trivia', number: tNumber);
const NumberTrivia tNumberTriviaEntity = tNumberTriviaModel;
group('when device is online', () {
test(
'should return remote data when call to remote data source is successful',
() async {
//arrange
when(mockRemoteDataSource.getConcreteNumberTrivia(any))
.thenAnswer((_) async => tNumberTriviaModel); ---> Line *
//act
final result = await repository.getConcreteNumberTrivia(tNumber);
//assert
verify(mockRemoteDataSource.getConcreteNumberTrivia(tNumber));
expect(result, equals(const Right(tNumberTriviaEntity)));
});
});
});
bellow I implemented the NumberTriviaRepository
class
class NumberTriviaRepositoryImpl implements NumberTriviaRepository {
NumberTriviaRemoteDataSource numberTriviaRemoteDataSource;
NumberTriviaRepositoryImpl(
{required this.numberTriviaRemoteDataSource});
@override
Future<Either<Failure, NumberTrivia>> getConcreteNumberTrivia(
int number) async {
return Right(
await numberTriviaRemoteDataSource.getConcreteNumberTrivia(number));
}
and when run the test I get a Mock.noSuchMethod
error :
MissingStubError: 'getConcreteNumberTrivia'
No stub was found which matches the arguments of this method call:
getConcreteNumberTrivia(1)
with an explanation which is: "Add a stub for this method using Mockito's 'when' API, or generate the MockNumberTriviaRemoteDataSource mock with a MockSpec with 'returnNullOnMissingStub: true' (see https://pub.dev/documentation/mockito/latest/annotations/MockSpec-class.html)."
The problem is I created a stub method for getConcreteNumberTrivia at line * but got error and don't have any idea how to fix this. By the way, I'm learning Clean Architecture using TestDrivenDevelopment so any comment would be appriciated.
use setUpAll() to initiate mocks and use when in setUpAll section
@GenerateMocks([NumberTriviaRemoteDataSource])
@GenerateMocks([NumberTriviaLocalDataSource])
@GenerateMocks([NetworkInfo])
void main() {
late final NumberTriviaRepositoryImpl repository;
late final MockNumberTriviaRemoteDataSource mockRemoteDataSource;
late final MockNumberTriviaLocalDataSource mockLocalDataSource;
late final MockNetworkInfo mockNetworkInfo;
const tNumber = 1;
const tNumberTriviaModel =
NumberTriviaModel(text: 'test trivia', number: tNumber);
const NumberTrivia tNumberTriviaEntity = tNumberTriviaModel;
setUpAll(() {
mockRemoteDataSource = MockNumberTriviaRemoteDataSource();
mockLocalDataSource = MockNumberTriviaLocalDataSource();
mockNetworkInfo = MockNetworkInfo();
repository = NumberTriviaRepositoryImpl(
numberTriviaRemoteDataSource: mockRemoteDataSource,
numberTriviaLocalDataSource: mockLocalDataSource,
networkInfo: mockNetworkInfo,
);
when(mockRemoteDataSource.getConcreteNumberTrivia(any))
.thenAnswer((_) async => tNumberTriviaModel);
});
group('getConcreteNumberTrivia', () {
//to make test manageable create variables
test('should check if the device is online', () {
//arrange
when(mockNetworkInfo.isConnected).thenAnswer((_) async => true);
// act
repository.getConcreteNumberTrivia(tNumber);
// assert
verify(mockNetworkInfo.isConnected);
});
group('when device is online', () {
setUp(() {
when(mockNetworkInfo.isConnected).thenAnswer((_) async => true);
});
test(
'should return remote data when call to remote data source is successful',
() async {
//arrange
when(mockRemoteDataSource.getConcreteNumberTrivia(any))
.thenAnswer((_) async => tNumberTriviaModel);
//act
final result = await repository.getConcreteNumberTrivia(tNumber);
//assert
verify(mockRemoteDataSource.getConcreteNumberTrivia(tNumber));
expect(result, equals(const Right(tNumberTriviaEntity)));
});
});
}