repoServiceBlocEventGroupTestUtil<Bloc extends RepoServiceBloc<GroupEvent> , GroupEvent extends Enum, DataType, ExecutorParams> function
Future<void>
repoServiceBlocEventGroupTestUtil<Bloc extends RepoServiceBloc<GroupEvent> , GroupEvent extends Enum, DataType, ExecutorParams>(
- Bloc repoServiceBlocFn(), {
- ExecutorParams? eventParams,
- String? eventKey,
- required GroupEvent groupEvent,
- required RepoServiceStubDefinition stub,
- void setUp(
- Bloc bloc
- void verifier(
- List<
RepoServiceBlocState< states,GroupEvent> > - Either<
Failure, DataType?> ? executorResult
- List<
- TypeMatcher<
BaseRequest> ? requestMatcher,
Example
void main() {
late ExampleRepoServiceBloc repoServiceBloc;
setUp(() {
GetIt.instance.registerSingleton<IHttpClient>(HttpClientMock());
repoServiceBloc = ExampleRepoServiceBloc();
});
test("$ExampleRepoServiceBloc test ${ExampleEvent.one}", () async {
final String responseFixture = fixture("modules/utils/repo_service_bloc_example_response.json");
await repoServiceBlocEventGroupTestUtil<ExampleRepoServiceBloc, ExampleEvent, List<ExampleModel>>(
() => repoServiceBloc,
groupEvent: ExampleEvent.one,
stub: RepoServiceStubDefinition.httpStub(
responseStubValue: responseFixture,
),
verifier: (states) {
expect(
states,
contains(
const TypeMatcher<RepoServiceBlocState<ExampleEvent>>().having(
(state) => state.data[ExampleEvent.one],
"ExampleEvent.one",
const TypeMatcher<LoadedData<List<ExampleModel>>>().having(
(p0) => p0.data,
"data",
isA<Right<Failure, List<ExampleModel>>>(),
),
),
),
);
},
);
});
}
enum ExampleEvent {
one,
second,
}
final mockUri = Uri.parse("https:///google.com");
List<ExampleModel> responseParser(String response) {
final data = jsonDecode(response);
List items = data["data"];
return items.map((e) {
return ExampleModel.fromMap(e);
}).toList();
}
class ExampleRepoServiceBloc extends RepoServiceBloc<ExampleEvent> {
ExampleRepoServiceBloc()
: super(
logger: null,
configurations: Map<ExampleEvent, RepoServiceConfiguration>.of({
ExampleEvent.one: BasicHttpRequestRepoServiceConfiguration<List<ExampleModel>>(
method: "POST",
uri: (_) => mockUri,
responseParser: responseParser,
initialState: LoadedData<List<ExampleModel>>(),
),
}),
);
}
Implementation
/// setUp(() {
/// GetIt.instance.registerSingleton<IHttpClient>(HttpClientMock());
/// repoServiceBloc = ExampleRepoServiceBloc();
/// });
/// test("$ExampleRepoServiceBloc test ${ExampleEvent.one}", () async {
/// final String responseFixture = fixture("modules/utils/repo_service_bloc_example_response.json");
/// await repoServiceBlocEventGroupTestUtil<ExampleRepoServiceBloc, ExampleEvent, List<ExampleModel>>(
/// () => repoServiceBloc,
/// groupEvent: ExampleEvent.one,
/// stub: RepoServiceStubDefinition.httpStub(
/// responseStubValue: responseFixture,
/// ),
/// verifier: (states) {
/// expect(
/// states,
/// contains(
/// const TypeMatcher<RepoServiceBlocState<ExampleEvent>>().having(
/// (state) => state.data[ExampleEvent.one],
/// "ExampleEvent.one",
/// const TypeMatcher<LoadedData<List<ExampleModel>>>().having(
/// (p0) => p0.data,
/// "data",
/// isA<Right<Failure, List<ExampleModel>>>(),
/// ),
/// ),
/// ),
/// );
/// },
/// );
/// });
/// }
/// enum ExampleEvent {
/// one,
/// second,
/// }
/// final mockUri = Uri.parse("https:///google.com");
/// List<ExampleModel> responseParser(String response) {
/// final data = jsonDecode(response);
/// List items = data["data"];
/// return items.map((e) {
/// return ExampleModel.fromMap(e);
/// }).toList();
/// }
/// class ExampleRepoServiceBloc extends RepoServiceBloc<ExampleEvent> {
/// ExampleRepoServiceBloc()
/// : super(
/// logger: null,
/// configurations: Map<ExampleEvent, RepoServiceConfiguration>.of({
/// ExampleEvent.one: BasicHttpRequestRepoServiceConfiguration<List<ExampleModel>>(
/// method: "POST",
/// uri: (_) => mockUri,
/// responseParser: responseParser,
/// initialState: LoadedData<List<ExampleModel>>(),
/// ),
/// }),
/// );
/// }
/// ```
/// {@endtemplate}
Future<void> repoServiceBlocEventGroupTestUtil<Bloc extends RepoServiceBloc<GroupEvent>, GroupEvent extends Enum,
DataType, ExecutorParams>(
Bloc Function() repoServiceBlocFn, {
ExecutorParams? eventParams,
String? eventKey,
required GroupEvent groupEvent,
required RepoServiceStubDefinition stub,
void Function(Bloc bloc)? setUp,
void Function(List<RepoServiceBlocState<GroupEvent>> states, Either<Failure, DataType?>? executorResult)? verifier,
TypeMatcher<BaseRequest>? requestMatcher,
// // /// [act] This lets you define a custom executor trigger, this is useful when you try to dispatch your event
// // /// with custom parameters
// // required void Function(Bloc bloc) act,
}) async {
Bloc repoServiceBloc = repoServiceBlocFn();
// validate if exists EventGroupConfig
RepoServiceConfiguration? configuration = repoServiceBloc.configurations[groupEvent];
List<RepoServiceBlocState<GroupEvent>> states = [];
StreamSubscription _subscription = repoServiceBloc.stream.listen((state) {
states.add(state);
});
if (configuration == null) {
throw ConfigurationNotDefinedForGroup(groupEvent);
}
Either<Failure, DataType?>? executorResult;
BaseRequest? eventRequest;
await configuration.map(
basicHttpRequest: (basicHttpRequestConfig) async {
if (stub is! _HttpStub) {
throw InvalidStubbingDefinition(_HttpStub, groupEvent);
}
if (repoServiceBloc.blocRepoServiceImpl.client is! HttpClientMock) {
throw InvalidHttpClientMock();
}
await repoServiceTestHttpUtil<RepoServiceBase, DataType>(
() => repoServiceBloc.blocRepoServiceImpl,
setUp: (clientMock) {
setUp?.call(repoServiceBloc);
},
act: (_) async {
repoServiceBloc.execute(
groupEvent,
params: eventParams,
key: eventKey,
);
return repoServiceBloc.events().firstWhere((event) {
return event.map(
actorExecutor: (actorExecutor) {
return false;
},
actorResult: (actorResult) {
return actorResult.executor.group == groupEvent;
},
);
}).then((value) {
return value.mapOrNull(
actorResult: (value) {
return value.result;
},
actorExecutor: null,
) as Either<Failure, DataType>;
});
},
verify: (client, response) async {
verify(
client.send(
argThat(
requestMatcher ??
const TypeMatcher<Request>().having(
(r) {
return r.toString();
},
"url",
contains(
basicHttpRequestConfig.uri(eventParams).toString(),
),
).having(
(r) {
return r.method;
},
"method",
basicHttpRequestConfig.method,
),
),
),
);
expect(response, isA<Either<Failure, DataType>>());
executorResult = response;
},
responseStubValue: stub.responseStubValue,
statusCodeStubValue: stub.statusCodeStubValue,
headersStubValue: stub.headersStubValue,
);
},
httpFromBaseRequest: (httpFromBaseRequestConfig) async {
if (stub is! _HttpStub) {
throw InvalidStubbingDefinition(_HttpStub, groupEvent);
}
if (repoServiceBloc.blocRepoServiceImpl.client is! HttpClientMock) {
throw InvalidHttpClientMock();
}
await repoServiceTestHttpUtil<RepoServiceBase, DataType>(
() => repoServiceBloc.blocRepoServiceImpl,
setUp: (clientMock) {
setUp?.call(repoServiceBloc);
},
act: (_) {
repoServiceBloc.execute(
groupEvent,
params: eventParams,
key: eventKey,
);
return repoServiceBloc.events().firstWhere((event) {
return event.map(
actorExecutor: (actorExecutor) {
return false;
},
actorResult: (actorResult) {
return actorResult.executor.group == groupEvent;
},
);
}).then((value) {
return value.mapOrNull(
actorResult: (value) {
return value.result;
},
actorExecutor: null,
) as Either<Failure, DataType>;
});
},
verify: (client, response) async {
eventRequest = await httpFromBaseRequestConfig.request(eventParams);
verify(
client.send(
argThat(
requestMatcher ??
const TypeMatcher<BaseRequest>()
.having(
(p0) => p0.method,
"Request Method",
eventRequest!.method,
)
.having(
(p0) => p0.url.toString(),
"Request Uri",
eventRequest!.url.toString(),
),
),
),
).called(1);
expect(response, isA<Either<Failure, DataType>>());
executorResult = response;
},
responseStubValue: stub.responseStubValue,
statusCodeStubValue: stub.statusCodeStubValue,
headersStubValue: stub.headersStubValue,
);
},
generic: (genericConfig) async {
if (stub is! _GenericStub) {
throw InvalidStubbingDefinition(_GenericStub, groupEvent);
}
if (repoServiceBloc.blocRepoServiceImpl.client is! HttpClientMock) {
throw InvalidHttpClientMock();
}
await repoServiceTestGenericUtil<RepoServiceBase, DataType>(
() => repoServiceBloc.blocRepoServiceImpl,
setUp: () {
stub.setUp(eventParams);
},
act: (_) {
repoServiceBloc.execute(
groupEvent,
params: eventParams,
key: eventKey,
);
return repoServiceBloc.events().firstWhere((event) {
return event.map(
actorExecutor: (actorExecutor) {
return false;
},
actorResult: (actorResult) {
return actorResult.executor.group == groupEvent;
},
);
}).then((value) {
return value.mapOrNull(
actorResult: (value) {
return value.result;
},
actorExecutor: null,
) as Either<Failure, DataType>;
});
},
verify: (result) {
expect(result, isA<Either<Failure, DataType>>());
executorResult = result;
},
);
},
);
await Future.delayed(const Duration(milliseconds: 10));
verifier?.call(states, executorResult);
_subscription.cancel();
}