Skip to content

'verify' not throw Exception when using not mocked class. #807

Open
@DerJojo11

Description

@DerJojo11

Hey guys!

I noticed an unexpected behavior in a project. Normally, we use ‘verify’ on mocked classes to verify the call.
If you use an unmocked class, you get an error message that it needs to be mocked.

So far so good.

Now I have noticed that if you call a method that injects a mocked class, e.g. via GetIt, this error does not occur. Instead, ‘true’ is returned, which means that the test is valid. But the expected method call was not verified.

I got you guys, you all need a bit of code:

Code Example

Let's say we have a Repository and a Service:

import 'package:flutter/material.dart';
import 'package:injectable/injectable.dart';
import 'package:mockito_application_1/injectable/injectable.dart';
import 'package:mockito_application_1/test_repository.dart';

@lazySingleton
class TestService {
  final TestRepository testRepository = getIt();

  Future<void> doSthThenFetchIt({required String id}) async {
    debugPrint('We are doing sth here');
    testRepository.fetchSomething(id: id);
    debugPrint('We fetched the stuff');
  }
}
import 'package:flutter/material.dart';
import 'package:injectable/injectable.dart';

@lazySingleton
class TestRepository {
  Future<void> fetchSomething({required String id}) async {
    Future.delayed(Durations.medium4);
    debugPrint('Ok ok ok ok ok, cool cococococooool');
  }
}

And somewhere a Button will call the Service to doSthThenFetchIt

ElevatedButton(
                onPressed: () {
                  getIt<TestService>().doSthThenFetchIt(
                    id: 'SomeId',
                  );
                },
                child: Text('TheFooButton'))

Now we want to test that when we tap the button. The call doSthThenFetchIt will be used:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:mockito_application_1/injectable/injectable.dart';
import 'package:mockito_application_1/main.dart';
import 'package:mockito_application_1/test_repository.dart';
import 'package:mockito_application_1/test_service.dart';

import 'mocks/mocks.mocks.dart';

void main() {
  late TestService testService;
  late MockTestRepository mockTestRepository;

  setUp(() {
    mockTestRepository = MockTestRepository();
    getIt.registerSingleton<TestRepository>(mockTestRepository);

    testService = TestService();

    getIt.registerSingleton(testService);
    getIt.allowReassignment = true;
  });

  testWidgets(
    'verify tap on ElevatedButton will call TestService.doSthThenFetchIt with correct id',
    (tester) async {
      await tester.pumpWidget(const MyApp());

      await tester.tap(find.byType(ElevatedButton));

      verify(
        testService.doSthThenFetchIt(id: 'SomeId'),
      );
    },
  );
}

Now, this test is valid and will return true.
However, the call is not correct. Since I do not test whether the service is called correctly, but our verify now checks the repository.
If I now change the value of the Id and set it manually in the repository call, this is also correct.

Unfortunately, this makes the verify invalid.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions