【发布时间】:2021-02-10 10:34:07
【问题描述】:
我真的很困惑如何让集团发出初始状态。 bloc.state 发出最新状态。由于新 bloc 库中没有可用的 @override initialState,因此将 initialState 传递给了超级构造函数。但是 bloc 仍然不会发出 initialState,在这种情况下是 Empty()。
number_trivia_bloc.dart
import 'package:clean_architecture/core/error/failure.dart';
import 'package:clean_architecture/core/utils/input_converter.dart';
import 'package:clean_architecture/features/number_trivia/domain/usecases/get_concrete_number_trivia_repository.dart';
import 'package:clean_architecture/features/number_trivia/domain/usecases/get_random_number_trivia.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'number_trivia_state.dart';
import 'number_trivia_event.dart';
const SERVER_FAILURE = 'Server failure';
const CACHE_FAILURE = 'Cache failure';
const INVALID_INPUT_FAILURE =
'Invalid Input Failure - The input should not be a negative integer or zero';
class NumberTriviaBloc extends Bloc<NumberTriviaEvent, NumberTriviaState> {
final GetConcreteNumberTrivia getConcreteNumberTrivia;
final GetRandomNumberTrivia getRandomNumberTrivia;
final InputConverter inputConverter;
NumberTriviaBloc({
// Changed the name of the constructor parameter (cannot use 'this.')
@required GetConcreteNumberTrivia concrete,
@required GetRandomNumberTrivia random,
@required this.inputConverter,
// Asserts are how you can make sure that a passed in argument is not null.
// We omit this elsewhere for the sake of brevity.
}) : assert(concrete != null),
assert(random != null),
assert(inputConverter != null),
getConcreteNumberTrivia = concrete,
getRandomNumberTrivia = random,
super(Empty());
@override
Stream<NumberTriviaState> mapEventToState(
NumberTriviaEvent event,
) async* {
if (event is GetTriviaForConcreteNumber) {
final inputEither =
inputConverter.stringToUnsignedInteger(event.numberString);
yield* inputEither.fold(
(failure) async* {
yield Error(message: INVALID_INPUT_FAILURE);
},
(integer) async* {
yield Loading();
},
);
}
}
}
number_trivia_bloc_test.dart
import 'package:clean_architecture/core/utils/input_converter.dart';
import 'package:clean_architecture/features/number_trivia/data/models/number_trivia_model.dart';
import 'package:clean_architecture/features/number_trivia/domain/entities/number_trivia.dart';
import 'package:clean_architecture/features/number_trivia/domain/usecases/get_concrete_number_trivia_repository.dart';
import 'package:clean_architecture/features/number_trivia/domain/usecases/get_random_number_trivia.dart';
import 'package:clean_architecture/features/number_trivia/presentation/bloc/number_trivia_bloc.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:clean_architecture/features/number_trivia/presentation/bloc/number_trivia_state.dart';
import 'package:clean_architecture/features/number_trivia/presentation/bloc/number_trivia_event.dart';
import 'package:mockito/mockito.dart';
class MockGetConcreteNumberTrivia extends Mock
implements GetConcreteNumberTrivia {}
class MockGetRandomNumberTrivia extends Mock implements GetRandomNumberTrivia {}
class MockInputConverter extends Mock implements InputConverter {}
void main() {
NumberTriviaBloc bloc;
MockGetConcreteNumberTrivia mockGetConcreteNumberTrivia;
MockGetRandomNumberTrivia mockGetRandomNumberTrivia;
MockInputConverter mockInputConverter;
setUp(() {
mockGetConcreteNumberTrivia = MockGetConcreteNumberTrivia();
mockGetRandomNumberTrivia = MockGetRandomNumberTrivia();
mockInputConverter = MockInputConverter();
bloc = NumberTriviaBloc(
concrete: mockGetConcreteNumberTrivia,
random: mockGetRandomNumberTrivia,
inputConverter: mockInputConverter,
);
});
test('initialState should be Empty', () {
// assert
expect(bloc.state, equals(Empty()));
});
group('GetTriviaForNumber', () {
String str = '1';
int parsedStr = int.parse(str);
NumberTrivia tTrivia =
NumberTriviaModel(text: 'test text', number: parsedStr);
test('Should convert a string to an unsigned integer', () async {
//arrange
when(mockInputConverter.stringToUnsignedInteger(any))
.thenReturn(Right(parsedStr));
//act
bloc.add(GetTriviaForConcreteNumber(str));
await untilCalled(mockInputConverter.stringToUnsignedInteger(str));
//assert
verify(mockInputConverter.stringToUnsignedInteger(any));
});
test('Should return [Error] for InvalidInputFailure', () async {
//arrange
when(mockInputConverter.stringToUnsignedInteger(any))
.thenReturn(Left(InvalidInputFailure()));
//assert later
final expected = [
Empty(),
Error(message: INVALID_INPUT_FAILURE),
];
expectLater(bloc, emitsInOrder(expected));
//act
bloc.add(GetTriviaForConcreteNumber(str));
});
});
}
它应该可以工作,但我得到的只是这个错误在向我尖叫。我尝试 bloc.cast()、bloc.asBroadcastStream()。似乎没有任何效果。所以,请有人帮我解决这个问题。提前致谢。
【问题讨论】:
-
我在flutter_bloc上遇到了同样的问题:^6.0.6。您应该提及您的集团版本。
-
我在
flutter_bloc: ^5.0.1上测试过它。