Search code examples
dartdart-unittest

Dart How to mock a procedure


How do I go about mocking a procedure (as apposed to a function see here)

For example, given the following typedef and procedure,

typedef int Adder(int a, int b);

int useAdder(Adder adder) {
  return adder(1, 2);
}

How could you write a mock that would allow you to test that the userAdder procedure called you mocked function?

This was my attempt, but it fails with the message that test failed: Caught The null object does not have a method 'call'.

class MyMock extends Mock {
  MyMock(){
    when(callsTo('call')).alwaysCall(this.foo);
  }
  int foo(int a, int b) => a+b;
}

void main() {

  test("bb", () {
    var mockf = new MyMock();
    expect(useAdder( mockf.call), 3);
    mockf.getLogs(callsTo('call', 1, 2)).verify(happenedOnce);
  });
}

If I change

 expect(useAdder( mockf.call), 3);

to

 expect(useAdder( mockf.foo), 3);

the method call does not appear in the log


Solution

  • My attempt

    import 'package:unittest/unittest.dart';
    import 'package:mock/mock.dart';
    
    typedef int Adder(int a, int b);
    
    int useAdder(Adder adder) {
      return adder(1, 2);
    }
    
    class MyMock extends Mock {
      MyMock(){
        when(callsTo('call')).alwaysCall(this.foo);
      }
      int foo(int a, int b) => a+b;
    
      int call(int a, int b) => super.call(a, b);
    
    }
    
    void main() {
    
      test("bb", () {
        var mockf = new MyMock();
        expect(useAdder(mockf as Adder), 3);
        mockf.getLogs(callsTo('call', 1, 2)).verify(happenedOnce);
      });
    }
    

    It seems the call method has to actually exist to make MyMock being accepted as Adder.