render function Null safety
- ReactElement ui,
- {Node? container,
- Node? baseElement,
- bool hydrate = false,
- dynamic wrapper,
- bool autoTearDown = true,
- void onDidTearDown(
Renders the ui
element into the DOM, returning a RenderResult API that can be used
to do things like RenderResult.rerender with different props, or to call
a query function scoped within the container
that was rendered into.
By default, the container
will be removed from the DOM and RenderResult.unmount will be called
along with an optional onDidTearDown
in the tearDown
of any test that calls this
function unless autoTearDown
is set to false.
See: testing-library.com/docs/react-testing-library/api#render
Example
import 'package:react/react.dart' as react;
import 'package:test/test.dart';
import 'package:react_testing_library/react_testing_library.dart' as rtl;
import 'package:react_testing_library/matchers.dart' show isInTheDocument;
main() {
test('', () {
final view = rtl.render(
react.button({}, 'Click Me'),
);
// The `view` can now be used to query within the DOM!
expect(view.getByRole('button', name: 'Click Me'), isInTheDocument);
});
}
Options
container
By default, render
will create a <div>
and append that <div>
to document.body
and this is where your
React component will be mounted/rendered. If you specify your own Node via the container
option,
it will not be appended to the document.body automatically.
For example: If you are unit testing a <tbody>
element, it cannot be a child of a <div>
.
In this case, you can specify a <table>
as the render container
:
import 'dart:html';
import 'package:react/react.dart' as react;
import 'package:test/test.dart';
import 'package:react_testing_library/react_testing_library.dart' as rtl;
main() {
test('', () {
final tableElem = document.body.append(TableElement());
final view = rtl.render(
react.tbody({}, /*...*/),
container: tableElem,
);
});
}
baseElement
If the container
is specified, then baseElement
defaults to that Node,
otherwise this defaults to document.body
. This is used as the base element
for the queries as well as what is printed when you use RenderResult.debug.
wrapper
An OverReact UiFactory
or a ReactComponentFactoryProxy which will be wrapped around the ui
.
This is especially useful when testing components that need a context provider of some kind.
Custom Queries Not Yet Supported
The JS react-testing-library implementation of
render
supports "custom queries". At this time, the Dart API does not support them. If you have a use case for custom queries - we would love to hear more about it!
Implementation
RenderResult render(
ReactElement ui, {
Node? container,
Node? baseElement,
bool hydrate = false,
// TODO: Implement if CPLAT-13502 is deemed necessary
// Map<String, Query> queries,
/*UiFactory || ReactComponentFactoryProxy*/ dynamic wrapper,
bool autoTearDown = true,
void Function()? onDidTearDown,
}) {
// ignore: invalid_use_of_visible_for_testing_member
componentZone = Zone.current;
final renderOptions = RenderOptions()..hydrate = hydrate;
if (container != null) renderOptions.container = container;
if (baseElement != null) renderOptions.baseElement = baseElement;
if (wrapper != null) {
if (wrapper is ReactComponentFactoryProxy) {
renderOptions.wrapper = wrapper.type;
} else {
// Its probably a UiFactory
try {
renderOptions.wrapper = wrapper().componentFactory.type;
} catch (err) {
throw ArgumentError.value(wrapper, 'wrapper', 'wrapper must be a ReactComponentFactoryProxy or UiFactory');
}
}
}
if (!autoTearDown && onDidTearDown != null) {
throw ArgumentError('onDidTearDown cannot be set when autoTearDown is false.');
}
return spyOnConsoleLogs(
() {
final jsResult = _render(ui, renderOptions);
if (autoTearDown) {
addTearDown(() {
jsResult.unmount();
jsResult.container.remove();
onDidTearDown?.call();
});
}
return RenderResult._(jsResult, ui);
},
configuration: ConsoleConfig.error,
onLog: (error) =>
print('\x1B[33m⚠️ Warning: ${error.replaceFirst(RegExp(r'^Warning:?\s?', caseSensitive: false), '')}\x1B[0m'),
);
}