Testing
Testing a client application can be a crucial part of ensuring its functionality and performance. When it comes to mobile/web applications, spinning up a full server to test against may not always be the best option. In the following sections, we will go through a couple of alternatives.
Widget Testing
Section titled “Widget Testing”For widgets that interface with Connect, it will generally be preferable to mock your RPCs since a backend may not be
available or desirable to access in a unit test. The easiest way to do this is via Connect’s FakeTransportBuilder
Mocking Transports
Section titled “Mocking Transports”FakeTransportBuilder from package:connectrpc/test.dart creates an in-memory
server with your own RPC implementations. It allows you to mock a backend to cover different behaviors in your widget.
To illustrate, let’s set up a very simple ELIZA service:
import 'package:connectrpc/connect.dart';import 'package:connectrpc/test.dart';import './gen/eliza.connect.spec.dart';
final fakeTransport = FakeTransportBuilder().unary( ElizaService.say, (_, __) async { return SayResponse(sentence: 'I feel happy.'); },).build();It exposes four methods: unary, server, client, and bidi. All of them accept
a Spec type. This can be obtained from the generated *.connect.spec.dart files.
Under the hood, this fake transport behaves like a server. This means that you can access request headers, raise errors with details, and also mock streaming responses. Here is an example that raises an error on the fourth request:
var sentences = <String>[];final fakeTransport = FakeTransportBuilder().unary( ElizaService.say, (req, context) async { sentences.add(req.sentence); if (sentences.length > 3) { throw ConnectException( Code.resourceExhausted, "I have no words anymore.", ); } context.responseHeaders.add("foo", "bar"); return SayResponse(sentence: 'I feel happy.'); },).build();You can also use expectations to assert that your client sends requests as expected:
final fakeTransport = FakeTransportBuilder().unary( ElizaService.say, (req, _) async { expect(req.sentence, "how do you feel?"); return SayResponse(sentence: 'I feel happy.'); },).build();The FakeTransportBuilder can be chained to provide mocks for multiple methods:
final fakeTransport = FakeTransportBuilder().unary( ElizaService.say, (req, _) async { return SayResponse(sentence: 'I feel happy.'); },).server(ElizaService.converse, (req, _) async* { yield ConverseResponse();}).build();