如何在Dart中测试流
如何在dart中测试流?我有以下代码:如何在Dart中测试流,dart,reactive-programming,Dart,Reactive Programming,如何在dart中测试流?我有以下代码: test('单词按顺序正确读取',(){ WordTrackerInterface wordTracker=wordTracker.byContent('0 1 2'); setWordScontPerchunk(1); var stream=wordTracker.nextWordStringStream(); 期待( 流动 emitsInOrder(List.generate( 6,(i)=>i>2?单词(“”):单词(i.toString()); 对
test('单词按顺序正确读取',(){
WordTrackerInterface wordTracker=wordTracker.byContent('0 1 2');
setWordScontPerchunk(1);
var stream=wordTracker.nextWordStringStream();
期待(
流动
emitsInOrder(List.generate(
6,(i)=>i>2?单词(“”):单词(i.toString());
对于(int i=0;i<6;i++){
wordTracker.nextWord();
}
});
我需要测试成员数据Word::content
,它是字符串
,是否与emitsInOrder
中提供的数据相同
类似于流的以下内容:
expect(
流动
emitsInOrder(List.generate(
6,(i)=>i>2?单词(“”):单词(i.toString()),
expect((实际单词,预期单词){
返回实际的.content==预期的.content;
}));
尝试使用async
/wait
和expectLater
test('words are reading sequentially correct', () async {
WordTrackerInterface wordTracker = WordTracker.byContent('0 1 2');
wordTracker.setWordsCountPerChunk(1);
var stream = wordTracker.nextWordStringStream();
await expectLater(
stream,
emitsInOrder(List<Word>.generate(
6, (i) => i > 2 ? Word('') : Word(i.toString()))));
for (int i = 0; i < 6; i++) {
wordTracker.nextWord();
}
});
test('字按顺序读取正确',()异步{
WordTrackerInterface wordTracker=wordTracker.byContent('0 1 2');
setWordScontPerchunk(1);
var stream=wordTracker.nextWordStringStream();
待会儿(
流动
emitsInOrder(List.generate(
6,(i)=>i>2?单词(“”):单词(i.toString());
对于(int i=0;i<6;i++){
wordTracker.nextWord();
}
});
在阅读了dart文件中的源代码并在互联网上阅读之后,我找到了解决方案:我需要创建一个自定义匹配器。我在笔记本电脑上测试了以下代码,并引用了我的应用程序中的其他文件,如“WordTracker”,代码按预期运行
test('words are reading sequentially correct', () {
WordTrackerInterface wordTracker = WordTracker.byContent('0 1 2');
wordTracker.setWordsCountPerChunk(1);
var stream = wordTracker.nextWordStringStream();
expect(stream,
emitsInOrder(List<Word>.generate(6, (i) => i > 2 ? Word('') : Word(i.toString())).map<WordMatcher>(
(Word value) => WordMatcher(value))));
for (int i = 0; i < 6; i++) {
wordTracker.nextWord();
}
});
class WordMatcher extends Matcher {
Word expected;
Word actual;
WordMatcher(this.expected);
@override
Description describe(Description description) {
return description.add("has expected word content = '${expected.content}'");
}
@override
Description describeMismatch(
dynamic item,
Description mismatchDescription,
Map<dynamic, dynamic> matchState,
bool verbose
) {
return mismatchDescription.add("has actual emitted word content = '${matchState['actual'].content}'");
}
@override
bool matches(actual, Map matchState) {
this.actual = actual;
matchState['actual'] = actual is Word ? actual : Word('unknown');
return (actual as Word).content == expected.content;
}
}
test('单词按顺序正确读取',(){
WordTrackerInterface wordTracker=wordTracker.byContent('0 1 2');
setWordScontPerchunk(1);
var stream=wordTracker.nextWordStringStream();
期望(流),
emitsInOrder(List.generate(6,(i)=>i>2?Word(“”):Word(i.toString()).map(
(单词值)=>WordMatcher(值));
对于(int i=0;i<6;i++){
wordTracker.nextWord();
}
});
类WordMatcher扩展了Matcher{
期望词;
字实际;
WordMatcher(this.expected);
@凌驾
描述(描述){
返回description.add(“has expected word content='${expected.content}'”;
}
@凌驾
描述不匹配(
动态项,
描述不匹配描述,
地图匹配状态,
冗长的
) {
返回mistchdescription.add(“has实际发出的单词内容='${matchState['actual'].content}'”);
}
@凌驾
布尔匹配(实际、映射匹配状态){
this.actual=实际;
matchState['actual']=actual是单词?actual:单词('unknown');
return(实际为Word).content==expected.content;
}
}
如果流正在发射具有要测试的属性的对象,expectAsync1
可以帮助:
List<Record> expectedRecords = [record1, record2, record3];
int i = 0;
recordStream.listen(
expectAsync1<void,Record>(
(record) {
expect(record.name, expectedRecords[i].name);
i++;
},
max: -1)
);
每次流recordStream
发出记录时,都会运行该命令
expectAsync1
中的1
是所包含函数将接受的参数数。通常情况下,这是1(记录)
是上面的一个参数
对于上面的示例,expectAsync1
具有(可选)类型参数:
第二个类型参数Record
告诉封闭函数发出的流项属于Record
类型,允许我使用类似Record.name
的属性,而无需强制转换
第一个类型参数是封闭函数的返回类型。我使用了void
,因为所包含的函数没有返回任何内容,它只是运行一个expect
匹配器并迭代一个计数器,该计数器用于迭代我希望看到的记录列表(即expectedRecords
)
最大参数
您会注意到所附函数下方的max:-1
。这是expectAsync1
的一个可选但重要的参数,用于指定我们期望的流项目/事件的数量
如果未给出max
,则默认为1
,如果发出超过1个事件,则测试将失败
错误将被回调调用的次数超过预期次数(1)。
在上面的示例中,我使用了-1
,这意味着可以发出/测试无限的事件。如果要测试从流中获得的项目/事件的数量,可以指定一个非零数,否则测试将失败。我可以在上面的例子中使用max:3
RxDart
如果您使用的是RxDartBehaviorSubject
请记住,最近的流事件是在listen
时发出的。因此,在测试中,当您开始侦听/使用expectAsync1
时,将立即调用包含最近事件的函数
ReplaySubject
将在listen
嗨@Kevin,谢谢你的回答,但是你提供的并没有回答我的问题。我想在emitsInOrder内部检查从流中发出的内容是否为Word(object),以及类型为“String”的字段“content”是否与列表中提供的“String”相同。生成方法如下(此代码是假设的):expect(流,emitsInOrder(List.generate)(6,(I)=>I>2?Word(“”):Word(i.toString()),(Word-actual,Word-expected){return-actual.content==expected.content;});
(record) {
expect(record.name, expectedRecords[i].name);
i++;
}