gpt4 book ai didi

mocking - dart-模拟,按名称调用的方法名,重构失败

转载 作者:行者123 更新时间:2023-12-03 03:48:07 28 4
gpt4 key购买 nike

我使用了dart unittest框架和随附的Mock类as described

但是在模拟调用中有一个依赖关系,即:

..store.when(callsTo('isLocked')).thenReturn(false);

通过名称调用 isLocked方法的调用。如果有人重命名了 isLocked方法,则重构框架将不会重命名该调用。

我想知道反射(镜子)是否可以以某种方式提供帮助,但是我还没有找到解决方案。

干杯
彼得

最佳答案

通常,我会尽量避免 mock 类(除非它们利用诸如RESTful Web API之类的外部资源)是因为这个问题。如果类A模拟了类B的foo方法,但类B实际上已重命名了其foo方法fooBar,则测试仍将通过。但是,当类A尝试在运行时调用B.foo时,事情将崩溃。因此,我避免 mock 本地可用的任何内容。

幸运的是,与其他动态语言相比,Dart的情况要好一些。例如,您可以创建一个实现另一个类的类。因此,如果FakeB实现B,则可以向FakeB添加可以在测试A时使用的功能。

自然地,对于重构框架来说,要知道您的代码callTo('isLocked')实际上是指某种名为isLocked的方法,实际上已重命名为isReallyLocked,这有点多。但是,我认为查看镜像API的方向正确。例如,如果您可以编写callTo(isLocked。名称),那将是很好的。这样,VM可以为您的模拟提供更多检查。

自然,真正的目标是在API不匹配时使测试失败。我在使用mirrors API时做了一些尝试,我能想到的最好的方法是:

#import('dart:io');
#import("dart:mirrors");

void a() {
print("a");
}

void main() {
String thisFile = "file://${new Directory.current().path}/${new Options().script}";
print(currentMirrorSystem().libraries[thisFile].functions['a'].simpleName);
}

这段代码仍然使用“a”作为字符串,但是它的好处是,如果“a”作为函数不存在,它将被炸掉。这有点丑陋,但它正朝着您想要的方向发展。

您可以做的另一件事是:

when(callsTo('isLocked')).alwaysCall(isLocked)

在这种情况下,模拟系统只是在调用者和isLocked函数之间扮演中间人。这种方法有两个缺点:a)大概您是在尝试完全避免调用isLocked,否则您将不会使用模拟框架b)isLocked是重复的,首先是字符串,然后是函数。但是,它确实有一些好处:a)它使您可以记录isLocked被调用的事实b)如果isLocked重命名,它将不起作用;即重命名isLocked的人将看到此代码,并希望更新两个地方。

另一种“强力”方法如下:

void a() {
print("a");
}

String makeSureItExists(obj, String name) {
return obj != null ? name : "NoSuchMethod";
}

void main() {
print(makeSureItExists(a, "a"));
}

这使您可以编写类似于callsTo(makeSureItExists(login,“login”))的内容。

关于mocking - dart-模拟,按名称调用的方法名,重构失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12386432/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com