You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Mockito测试MessageBloc报错:返回类型Null非Future<Message>

解决Mockito测试MessageBloc时返回类型不匹配问题

问题场景

在使用Mockito测试Flutter的MessageBloc时,遇到类型错误:返回类型'Null'不符合闭包上下文要求的'Future',错误出现在thenAnswer返回null的代码行:

import 'package:chat/chat.dart';
import 'package:flutter_newapp/src/blocs/message/message_bloc.dart';
import 'package:flutter_newapp/src/blocs/message/message_event.dart';
import 'package:flutter_newapp/src/blocs/message/message_state.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

class FakeMessageService extends Mock implements IMessageService {}

void main() {
  late MessageBloc sut;
  late IMessageService messageService;
  User user;

  setUp(() {
    messageService = FakeMessageService();
    user = User(
        username: 'test', photoUrl: '', active: true, lastSeen: DateTime.now());
    sut = MessageBloc(messageService);
  });

  tearDown(() => sut.close());

  test('it should emit initial state before Subscription',
      () => expect(sut.state, MessageInitial()));

  test('should emit message sent state when message is sent', () {
    final message = Message(
        from: '1234',
        to: '123',
        timestamp: DateTime.now(),
        contents: 'Hellllo');
    when(messageService.send([message])).thenAnswer((_) async => null); // 此处报错
    sut.add(MessageEvent.onMessageSent([message]));
    expectLater(sut.stream, emits(MessageState.sent(message)));
  });
}

问题原因

IMessageService的send方法定义返回类型为Future<Message>,在Dart非空安全规则下,不能返回null。测试中用async => null模拟返回值,违反了类型约束,导致报错。不需要重写IMessageService的方法,只需修正模拟的返回值即可。

解决方案

将thenAnswer的返回值替换为一个合法的Message实例,比如直接返回传入的消息对象,或者构造一个符合业务逻辑的已发送消息实例:

修改后的测试代码

test('should emit message sent state when message is sent', () {
  final message = Message(
      from: '1234',
      to: '123',
      timestamp: DateTime.now(),
      contents: 'Hellllo');
  // 模拟send方法返回传入的message(或根据业务构造处理后的消息)
  when(messageService.send([message])).thenAnswer((_) async => message); 
  sut.add(MessageEvent.onMessageSent([message]));
  expectLater(sut.stream, emits(MessageState.sent(message)));
});

如果业务中send方法会返回带标识的已发送消息(比如自动生成ID),可以构造对应的实例:

test('should emit message sent state when message is sent', () {
  final originalMessage = Message(
      from: '1234',
      to: '123',
      timestamp: DateTime.now(),
      contents: 'Hellllo');
  // 构造模拟的已发送消息,带业务所需的属性
  final sentMessage = Message(
      id: 'mock-sent-id',
      from: '1234',
      to: '123',
      timestamp: DateTime.now(),
      contents: 'Hellllo');
  
  when(messageService.send([originalMessage])).thenAnswer((_) async => sentMessage); 
  sut.add(MessageEvent.onMessageSent([originalMessage]));
  expectLater(sut.stream, emits(MessageState.sent(sentMessage)));
});

内容的提问来源于stack exchange,提问作者FERHATI KHALIL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:02:29