用飞镖嘲讽 - 如何测试,作为一个参数传递的函数被调用?(Mocking with Dart - H

2019-10-19 02:49发布

诚然,这是一个奇怪的测试用例一点点,但它是我在给跑了问题。 我有一个类,它的功能,如它的构造函数的参数。 我想知道这是否传递函数被调用。 下面是一个例子:

class TestClassMock extends Mock implements RealClass {
  RealClass _real;

  TestClassMock() {
    _real = new RealClass();

    when(callsTo("myNamedFunction")).alwaysCall(_real.myNamedFunction);
  }
}

class RealClass {
  String _name = "RealClass";
  Function myNamedFunction;

  RealClass() {
    myNamedFunction = _theNamedFunction;
  }

  String _theNamedFunction() {
    return _name;
  }
}

class ClassThatCallsRealClass {
  ClassThatCallsRealClass(Function func) {
    func();
  }
}

//The test
TestClassMock testClassMock = new TestClassMock();
ClassThatCallsRealClass caller = new ClassThatCallsRealClass(testClassMock.myNamedFunction);  
testClassMock.getLogs(callsTo("myNamedFunction")).verify(happenedOnce);

所以要解释一下,ClassThatCallsRealClass接受一个函数作为参数,并调用它。 如果你要传递(实例RealClass).myNamedFunction,这将反过来呼吁RealClass私有函数_theNamedFunction。 但是,如果你试图嘲弄RealClass并重定向从myNamedFunction到RealClass myNamedFunction所有呼叫,这似乎失败。 我没有看到任何明显的方法来得到这个工作,但我觉得这是可能的。

有任何想法吗?

Answer 1:

在飞镖,所有功能都类的实例Function ,你知道,因为你传递的一个实例FunctionClassThatCallsRealClass构造。 的实例Function有一个方法call()如图所示在这里 。

同时,飞镖描述了一个非常不错的嘲讽能力在这里 (与感谢@KWalrath进行更新)。

因此,所有你需要做的是一个像任何其他对象嘲弄的考验。 正如文献中记载,创建一个间谍ClassThatCallsRealClass并为您的一个模拟Function实例。 然后使用verify(happenedOnce)上的call()的函数的方法。

嘲笑你的函数做到这一点:

class MockFunction extends Mock {
  call(int a, int b) => a + b;
}

var mock = new MockFunction();
mock(1,2); //returns 3

当然,参数列表来call将匹配,真正的功能。 通过mock对您的间谍ClassThatCallsRealClass



Answer 2:

这为我工作:

library x;

import "package:unittest/unittest.dart";
import "package:unittest/mock.dart";

class TestClassMock extends Mock implements RealClass {
  RealClass _real;

  TestClassMock() {
    _real = new RealClass();

    when(callsTo("myNamedFunction")).alwaysCall(_real.myNamedFunction);
  }
}

class RealClass {
  String _name = "RealClass";
  Function myNamedFunction;

  RealClass() {
    myNamedFunction = _theNamedFunction;
  }

  String _theNamedFunction() {
    return _name;
  }
}

class ClassThatCallsRealClass {
  ClassThatCallsRealClass(Function func) {
    func();
  }
}

class MyFunc implements Function {

  Function func;
  String functionName;

  MyFunc(this.func, this.functionName);

  call() {
    var inv = new MyInvocation(functionName);
    func(inv);
  }
}

main(List<String> args) {
  test('xx', () {
    //The test
    TestClassMock testClassMock = new TestClassMock();
    ClassThatCallsRealClass caller = new ClassThatCallsRealClass(new MyFunc(testClassMock.noSuchMethod, "myNamedFunction"));  
    testClassMock.getLogs(callsTo("myNamedFunction")).verify(happenedOnce);
  });
}

class MyInvocation extends Invocation {
  final String f;
  MyInvocation(this.f); 

  bool get isGetter => false;

  bool get isMethod => true;

  bool get isSetter => false;

  Symbol get memberName => new Symbol(f);

  Map<Symbol, dynamic> get namedArguments => {};

  List get positionalArguments => [];
}

testClassMock.myNamedFunction所以我打电话noSuchMethod直接代替它需要一个调用返回null。 调用是抽象的,所以我创建了一个实现。 MYFUNC是一个封装功能的类。 MYFUNC可以因为它实现了调用方法被调用的函数。



文章来源: Mocking with Dart - How to test that a function passed as a parameter was called?
标签: dart