如何在 Flutter 中测试渲染对象的内在大小
Posted
技术标签:
【中文标题】如何在 Flutter 中测试渲染对象的内在大小【英文标题】:How to test the intrinsic size of a render object in Flutter 【发布时间】:2020-03-22 17:25:17 【问题描述】:我之前问过testing the size of a widget in Flutter。
但是,现在我正在尝试测试底层渲染对象的内在大小。
我试过这样做
testWidgets('MongolRichText has correct min instrinsic width',
(WidgetTester tester) async
const String myString = 'A string';
await tester.pumpWidget(
Center(child: MongolText(myString)),
);
MongolRenderParagraph text = tester.firstRenderObject(find.byType(MongolRenderParagraph));
expect(text, isNotNull);
expect(text.getMinIntrinsicHeight(double.infinity), 100);
);
MongolText
在哪里创建 MongolRenderParagraph
(类似于 Text
最终创建 Paragraph
的方式)。但是,我收到以下错误:
══╡ FLUTTER 测试框架发现异常╞════════════ 运行测试时引发以下 StateError: 不良状态:无元素
如何让底层渲染对象对其运行测试?
我找到了答案,所以我将其添加为自我回答问答。我的答案如下。
【问题讨论】:
【参考方案1】:你可以直接创建渲染对象,所以你不需要抽小部件。
这里有一个简单的例子:
testWidgets('MongolRichText has correct min instrinsic width', (WidgetTester tester) async
MongolRenderParagraph paragraph = MongolRenderParagraph(TextSpan(text: 'A string'));
final double textWidth = paragraph.getMaxIntrinsicWidth(double.infinity);
expect(textWidth, greaterThan(0));
);
我通过查看 Flutter source code for paragraph_intrinsics_test.dart 找到了解决方案:
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/rendering.dart';
import '../flutter_test_alternative.dart';
void main()
test('list body and paragraph intrinsics', ()
final RenderParagraph paragraph = RenderParagraph(
const TextSpan(
style: TextStyle(height: 1.0),
text: 'Hello World',
),
textDirection: TextDirection.ltr,
);
final RenderListBody testBlock = RenderListBody(
children: <RenderBox>[
paragraph,
],
);
final double textWidth = paragraph.getMaxIntrinsicWidth(double.infinity);
final double oneLineTextHeight = paragraph.getMinIntrinsicHeight(double.infinity);
final double constrainedWidth = textWidth * 0.9;
final double wrappedTextWidth = paragraph.getMinIntrinsicWidth(double.infinity);
final double twoLinesTextHeight = paragraph.getMinIntrinsicHeight(constrainedWidth);
final double manyLinesTextHeight = paragraph.getMinIntrinsicHeight(0.0);
// paragraph
expect(wrappedTextWidth, greaterThan(0.0));
expect(wrappedTextWidth, lessThan(textWidth));
expect(oneLineTextHeight, lessThan(twoLinesTextHeight));
expect(twoLinesTextHeight, lessThan(oneLineTextHeight * 3.0));
expect(manyLinesTextHeight, greaterThan(twoLinesTextHeight));
expect(paragraph.getMaxIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(paragraph.getMaxIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(paragraph.getMaxIntrinsicHeight(0.0), equals(manyLinesTextHeight));
// vertical block (same expectations)
expect(testBlock.getMinIntrinsicWidth(double.infinity), equals(wrappedTextWidth));
expect(testBlock.getMaxIntrinsicWidth(double.infinity), equals(textWidth));
expect(testBlock.getMinIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(testBlock.getMinIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(testBlock.getMaxIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(testBlock.getMinIntrinsicWidth(0.0), equals(wrappedTextWidth));
expect(testBlock.getMaxIntrinsicWidth(0.0), equals(textWidth));
expect(testBlock.getMinIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
expect(testBlock.getMinIntrinsicHeight(0.0), equals(manyLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(0.0), equals(manyLinesTextHeight));
// horizontal block (same expectations again)
testBlock.axisDirection = AxisDirection.right;
expect(testBlock.getMinIntrinsicWidth(double.infinity), equals(wrappedTextWidth));
expect(testBlock.getMaxIntrinsicWidth(double.infinity), equals(textWidth));
expect(testBlock.getMinIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(testBlock.getMinIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(testBlock.getMaxIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(testBlock.getMinIntrinsicWidth(0.0), equals(wrappedTextWidth));
expect(testBlock.getMaxIntrinsicWidth(0.0), equals(textWidth));
expect(testBlock.getMinIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
expect(testBlock.getMinIntrinsicHeight(0.0), equals(manyLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(0.0), equals(manyLinesTextHeight));
);
【讨论】:
我仍然想知道为什么tester.firstRenderObject()
不起作用。以上是关于如何在 Flutter 中测试渲染对象的内在大小的主要内容,如果未能解决你的问题,请参考以下文章