是否可以在Dart中使用mockito
插件模拟或伪造一个需要用其他类扩展的类?
我有以下继承的例子:
abstract class Animal {
Animal(this.emoji);
final String emoji;
String greet();
}
class Dog extends Animal {
Dog(super.emoji);
@override
String greet() {
return '$emoji: Woof!';
}
}
class Poodle extends Dog {
Poodle(super.emoji);
}
class FakePoodle extends Fake implements Poodle {
// Raises a runtime error:
// Runtime error: No associated positional super constructor parameter.
FakePoodle(super.emoji);
}
我想模拟类FakePoodle
,它仍然会继承类Dog
的所有属性,使用构造函数,并使它与mockito
同时为假。
以下是我的测试:
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
void main() {
group('Dog tests', () {
test('should return a dog greet', () {
expect(Dog('🐶').greet(), '🐶: Woof!');
});
test('Poodle should return a poodle greet', () {
expect(Poodle('🐩').greet(), '🐩: Woof!');
});
test('Fake Poodle should greet only once', () {
final FakePoodle fakePoodle = FakePoodle('🐕');
fakePoodle.greet();
verify(fakePoodle.greet());
});
});
}
我从mockito
插件中找到了以下常见问题部分:
如何模拟扩展方法?
如果没有办法覆盖某种函数,那么mockito就不能模拟它。有关进一步的解释和替代方法,请参见上面的答案。
有没有一种方法可以让我以一种干净的方式编写这样的集成测试?
2条答案
按热度按时间wfveoks01#
首先,a fake is different from a mock.Mock用于验证行为。(具体来说,它们用于验证 * 其他 * 对象与被模拟对象交互的行为。被模拟对象 * 不是 * 正在测试的对象。)您不能在
Fake
上使用verify
。如果您希望
FakePoodle
成为Fake
,但要重用Poodle
中的一些实现,则可以执行以下操作:但不清楚为什么要这样做,而不是仅仅使用实际的
Poodle
示例(除非Poodle
上有其他方法,如果调用这些方法,您希望它们抛出UnimplementedError
)。您可能需要一个 mock 来代替,因为您想使用
verify
。同样,它们被用来验证其他被测试对象的行为,因此模拟对象的实现通常不重要,希望模拟对象从基类继承一些实现与这种理念相冲突。但是如果你仍然想要一个mock,但是仍然想要重用实现(也许那个实现特别复杂,并且确定一个预先计算的stubbed响应是很重要的,或者也许那个实现有重要的副作用),那么你可以用调用真实的对象的stub来做一个
Mock
Package 器:最后,我会指出,如果
Mock
或Fake
不符合您的要求,您不必使用它们。也就是说,您还可以手动执行以下操作:顺便说一句,你的其他术语到处都是。“Extension methods“是完全不相关的。另外,“integration tests“是整体测试;他们通常不应该使用mock或fakes。mock和fakes通常被用来测试程序的一部分。
n53p2ov02#
你可以创建一个新类MockPoodle来扩展Poodle并覆盖greet()方法:
然后可以使用Mockito创建MockPoodle类的模拟对象,并验证是否调用了其greet()方法: