首页 > 解决方案 > Method (with optional parameter) mocked with mockito return null on unit test. Dart Flutter

问题描述

Im five hours trying solve it, doesn't work nothing. I wanna test bloc class that use stream and sink data after load data from internet. The use case test work well but the bloc class was a huge headache today, this already work on app, but the test I really dont know how to solve

file bloc.dart

class Bloc {
  final UseCase _useCase;
  Bloc(this._useCase);

  final _controller = StreamController.broadcast();

  Stream get stream => _controller.stream;

  doSomething() async {
    ResponseModel responseModel = await _useCase.call();
    _controller.sink.add(responseModel);//<-- I would like test this
  }

  dispose() {
    _controller.close();
  }
}

This is the unit test class bloc_test.dart


class UseCaseMock extends Mock implements UseCase {}

main() {
  UseCase useCase;
  Bloc bloc;
  setUp(() async {
    useCase = UseCaseMock();
    bloc = Bloc(useCase);
  });

  tearDown(() {
    bloc.dispose();
  });

  group('Test Bloc', () {
    test('load stuff must sink Response ', () async {
      when(useCase.call())
          .thenAnswer((_) async => ResponseModel('id','name'));
          
       //FIRST I TRY It, DOESNT WORK   
      // await expectLater( bloc.stream, emits(isA<ResponseModel>()));


      bloc.stream.listen((response) {
      
        //print(response) <-----return null  I THINK HERE IS THE PROBLEM
        expect(response, isA<ResponseModel>());
      });

      await bloc.doSomething();
    });
  });
}

Please, would you know how to solve it? Thanks

Solved here

标签: unit-testingflutterdartstreammockito

解决方案


解决了!我的用例有一个带有可选参数的方法“调用”

 Future<ResponseModel> call( {String value });

我在嘲笑错误如下

 when(useCase.call()) <----------------here is the error
          .thenAnswer((_) async => ResponseModel('id','name'));

在真正的 Bloc 类中(不是我发布的伪代码)我使用参数执行一个用例

// this is the true doSomething() method on my app
loadCoupons(String storeId) async {
    final result = await searchCouponUseCase(storeId: storeId);
    _controller.sink.add(result);
  }

解决方案是: 使用可选参数进行模拟(如果它会被调用)!我在没有参数的情况下进行测试,因为将“any”像 when(useCase.call( any )) 一样放入测试中时...无法编译。

 when(useCase.call(   value: ''    )) <-----solved
          .thenAnswer((_) async => ResponseModel('id','name'));

推荐阅读