spry icon indicating copy to clipboard operation
spry copied to clipboard

[Proposal] Testing support

Open miracoco opened this issue 1 year ago • 0 comments

Background

When writing HTTP server related tests, in most cases, we don't want actually start a HTTP server and use HTTP client to fetch the response, it will impact the testing execution time and write more redundant code.

Proposal

Provide APIs for single handler testing

Sometime, developers need to test single endpoint without routing to guarantee that the handler is working as expected behavior.

API example:

class SpryTestingServer {
  Future<HttpResponse> sendSingle(FutureOr Function(HttpRequest) handler, [void Function(HttpRequest)? configure]);
}

Usage example:

import 'dart:io';
import 'package:spry/testing.dart';
import 'package:test/test.dart';

void main() {
  test('expect remote server respond correct payload', () {
    final spryServer = SpryTestingServer();

    Future handle(HttpRequest request) async {
      return {'success': 'true', 'data': 'ok'};
    }
    
    final res = await spryServer.sendSingle(handle, (req) {
      req.write(json.encode({'clientId': 'e93b5045-ed30-4eec-aaab-1cd4c9cb8eb5', 'action': 'updateDeviceStatus', 'payload': {'battery': 80, 'voltage': 3.2, 'current': 0.5, 'networkQuality': 'GOOD'}}));
    });
    expect(res.statusCode, equals(200));
    expect(await res.asJson(), equals({'success': true, 'data': 'ok'}))
  });
}

Provide APIs for multiple endpoints testing with routing

API example:

class SpryTestingServer {
  void addHandler(String method, String path, FutureOr Function(HttpRequest) handler);
  Future<HttpResponse> send(String method, String path, [void Function(HttpRequest)? configure]);
}

Usage example:

import 'dart:io';
import 'package:spry/testing.dart';
import 'package:test/test.dart';

void main() {
  test('expect remote server respond correct payload', () {
    final spryServer = SpryTestingServer();

    Future getDevice(HttpRequest request) async {
      return {'success': 'true', 'data': {'deviceId': 'SN2305830131'}};
    }

    Future updateDevice(HttpRequest request) async {
      return {'success': 'true', 'data': 'ok'};
    }

    spryServer.addHandler('GET', '/api/v1/device/{deviceId}', getDevice);
    spryServer.addHandler('POST', '/api/v1/device/{deviceId}', updateDevice);
    
    final res = await spryServer.send('GET', '/api/v1/device/SN2305830131', (req) {
      req.write(json.encode({'clientId': 'e93b5045-ed30-4eec-aaab-1cd4c9cb8eb5', 'action': 'updateDeviceStatus', 'payload': {'battery': 80, 'voltage': 3.2, 'current': 0.5, 'networkQuality': 'GOOD'}}));
    });
    expect(res.statusCode, equals(200));
    expect(await res.asJson(), equals({'success': true, 'data': 'ok'}))
  });
}

miracoco avatar May 26 '24 00:05 miracoco