Suppose I have the below Parent.razor component:
<div>
<span>Below is a child component.</span>
<Child/>
</div>
Where Child is a very complex component Child.razor.
If I want to unit-test Parent.razor, how do I mock out <Child/> so that the test focuses on the Parent component alone? What libraries do I use?
Unless you design your Parent component such that it's Child components can be replaced at runtime (e.g. through a RenderFragment parameter), you cannot replace a component at runtime, and thus not mock it.
There is a change coming in .net 5 that will allow bUnit to do it, but for the current version of Blazor it's not possible.
Related
I know the concept of Data Down / Actions Up, but I'm facing a situation on which I don't know how to do it with the DDAU. I searched on differents forum and blogs how to do it, but it does not fit my request.
I have a controller with two components.
On the first component I have a header with a button.
On the second component I have a form.
When the button is clicked, an action is trigered and catched by the controller, but how can I notify the second component of the "click" on the button on the first component.
An easy solution would have been to include the first component in the second one, but I can't do this because each component are used in many different situations.
You can use services as a bus.
Register an event on second component and trigger that event from first component.
I show it in this twiddle
If you don't want using services you can use parent-child model.
Please take a look at that twiddle
You can pass foo property from controller to both components, and first component to pass action to controller to change foo. Now this sibling component too will be notified and you can make use of didUpdateAttrs hook in sibling component to react to change.
I have a "container" component
# components/container-component.js
import Ember from 'ember';
export default Ember.Component.extend({
displayComponent: 'simple-box'
});
The template is
# templates/container-component.hbs
<div>
{{component displayComponent}}
</div>
Now, from within "container-component" instance. How can I access the computed "displayComponent" instance?
Any ideas on how I could go about it?
When I use the get method I get the string identification of the component
this.get('displayComponent')
# returns (String) 'simple-box'
There is not a built-in way of retrieving children components from the parent component's js file as far as I know. If you really want to achieve this, please refer to my twiddle I have prepared for you.
As you can see from the code; within the template parent passes itself to the child and child registers itself to the parent. Note that this is an illustration of code smell and this is something I never use in my projects.
Because, in my opinion what you are trying to achieve is a clear violation of many principles that ember is built upon. Why do you want to get the child property from the parent directly? You can register actions to child component and get notified for various events within the child component. Why do you need direct access? It is better for a component to be working independently by itself. In this kind of approach you are polluting parent's code with child component's internal design considerations. You can query DOM tree via jquery within parent but getting the child component instance created for you by Ember infrastructure is a sign that you are trying to design something that is out of Ember's approach. We can help you better if you post another question (or modify this one) to describe your intention. May be someone could lead you to a better design. Best Regards.
I'm trying to figure out why an Ember component is not working (and trying to learn about component lifecycles in the process). The component in question is Ember-cli-mapbox. It uses nested components. You can have a mapbox-map component, and within that component you can have several mapbox-marker components. Now, how it is supposed to work, is the mapbox-map component initialises the map, and then passes a block to the child marker components. The child marker components then references the map that got passed down to them. An example of the components in use (which come from the component docs):
{{#mapbox-map mapId='ember-cli-mapbox.7c3914f2' as |map|}}
{{#each positions as |position|}}
{{mapbox-marker map=map coordinates=position.coordinates}}
{{/each}}
{{/mapbox-map}}
Now, the components get set up using the didInsertElement hook, which makes sense to me since the DOM needs to be in place before the mapbox-map component can bind to a element in the dom. It doesn't work like that though. The didInsertElement of the child components get executed before the didInsertElement hook in the parent component. So, the marker tries to reference the map before it was created. I figured this out by putting console.logs in the component init code. I can't find much documentation on component lifecycles. didInsertElement does get referenced in the API docs here, but it seems that the newest API docs are actually out of date and don't reference a bunch of other hooks described here. The latter link says that life cycle events happen in the following order:
didInitAttrs
didReceiveAttrs
willRender
didInsertElement
didRender
Now, things get weird. When I replace didInsertElement in the components with didInitAttrs, it fires in the correct order. The didInitAttrs hook on the parent component fires first, followed by the child component didInitAttrs hooks. Problem with this is, the DOM isn't ready yet, so it doesn't help much. I also can't put the map binding event in the Ember runloop, since it need to be returned and passed as a block to the child elements.
So, my questions are:
Why, when using didInsertElement on components, do the hooks get executed in the order they do? (children, then parents)
How did this component ever work in the way it's currently written?
Am I supposed to use the above mentioned hooks if they're not mentioned in the official API docs?
I've recreated the addon in an Ember Twiddle here. Child hooks get called before the parent hooks, causing the component to break since map is undefined when the hook is called. This happens on Ember 1.13.8 as well as 1.13.9.
Why, when using didInsertElement on components, do the hooks get
executed in the order they do? (children, then parents)
This was changed in version 1.8. It was previously parent, then children but this often required people to use some complicated method of waiting for children to render to do certain things. Changing the order made learning Ember simpler.
See https://github.com/emberjs/ember.js/issues/5631 for more information.
How did this component ever work in the way it's currently written?
I have not used this addon, and have no idea if it works or not. I fixed your twiddle to work, however: http://ember-twiddle.com/4c3e55d0a66ead378bdf
Am I supposed to use the above mentioned hooks if they're not
mentioned in the official API docs?
These hooks are not mentioned because the documentation is still catching up to changes in Ember. Feel free to use them if you'd like.
I'm using ember-cli and am writing some tests for my components. Is there a way (in the test) to pass in some block content to the component so that I can test the component use in block form?
No matter what you are passing to the component, it is just a template that is being wrapped by your component. Your unit test will be testing only the component which will remain the same regardless of the template it renders.
If you are trying to test how the component behaves during user interaction, you are talking about integration/acceptance tests. In that case you don't need to pass a block to the component because you'll be visiting routes that render templates where you have already set up your blocks.
I am new to writing unit tests.
I am trying to write a unit test for a tooltip Ember component. The usage pattern is
<div id="parent"> I have a tooltip</div>
{{tooltip-comp}}
tooltip content
{{/tooltip-comp}}
I am trying to check that clicking the parent div (with id parent), makes the 'isVisible' property true for the component.
Do I need to somehow insert a parent to DOM to be able to do this?
I am using Ember CLI.