I trying to test some components, and I would like to spy after an onPress but for some reason its not being called:
it('expect press', () => {
const listItem = wrapper.find('ListItem')
listItem.simulate('onPress')
console.log(mockFn.mock)
})
When I debugging the component, I can clearly see that I selected the right element, but yet the simulate do not happen :/
Change it to
listItem.simulate('Press')
Related
I have an emberjs file (child.js) that extends from an Abstract js file (Parent.js)
export default Parent.extend({
(...)
onPress: action(function() {
if (this.get('isValid') ) {
this.togglePropertyInParent();
}
})
(...)
})
Inside the parent component we have the boolean property set as false by default and also the togglePropertyInParent method.
I want to build a unit test that asserts using sinon that togglePropertyInParent was called once in but I cannot stub it properly...
test('The toggler gets called if the key is pressed', function(assert) {
const component = this.owner.factoryFor('component:child-component').create();
// The console logs in the parent are ok, meaning the send worked fine based on the isValid param
component.send('onPress');
sinon.assert.calledOnce(this.togglePropertyInParent);
});
How can I stub the parent in order to check if it was called?
What am I missing ?
How can I stub the parent in order to check if it was called? What am I missing ?
This is highly advised against.
Components should be tested as the user would interact with them (not just in ember, but this is a growing convention in all frameworks).
So, if you click a button to trigger some state, click that button with click from #ember/test-helpers.
If the visuals of the component change as a result of that click, assert that with assert.dom from qunit-dom.
I have a component named Message and a property named focus. If focus is true, a style with outline: none will be added. I want to check the opposite case also, that if focus is false, the outline style will be not existed.
I write the test case like this, however the value return is same as focus="true" (always check it have outline style)
test("render component without focus", () => {
const { container } = render(<Message focus={false} message={"Message"} />);
expect(container.firstChild).not.toHaveStyleRule("outline", "none");
});
Does anyone know what I am missing?
Thank all
This doesn't work for me. Please make the Plunkr below work.
describe("trying a test", () => {
beforeEach(() => {
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
TestBed.configureTestingModule({
declarations: [myCmp, ChildCmp]
});
});
it("test should work", () => {
const fixture = TestBed.createComponent(myCmp);
const div = fixture.debugElement.children[0];
const childCmp = div.queryAll(By.directive(ChildCmp));
const divEl = div.queryAll(By.css('div'));
divEl[0].triggerEventHandler('click', <Event>{});
fixture.detectChanges();
expect(childCmp[0].nativeElement.textContent).toBe("updated value");
});
});
https://plnkr.co/edit/wWJMDi3ZFC6RTSvCw4HH?p=preview
This is no longer an issue for me. For the most part (with one exception I will outline below), both my parent components and child components get updated in my real app code, though I haven't updated the Plunkr.
I just use .and.callThrough() on the spyed on parent component method that is called, when something is clicked on the template. Rather than a simple spy.
I do have an issue with ngFor rendered child components not updating. This is my other question: Angular 2 unit testing: Make ngFor rendered, child components' templates change?
How can I test that an action was called in a component?
There are multiple ways of triggering an action like clicking on a button. Now I want to test that the action that is called when clicking on that button is actually called. Something like expect.functionName.to.be.called or something.
I have the following code
test('it closes the create dialog when close btn is clicked', function(assert) {
this.render(hbs`{{group-create cancelCreateAction="cancelAction"}}`)
this.$('button.btn--primary').click()
expect('myAction').to.be.called?
})
so i'm just wondering what I can do there?
Well your action does something we don't know. But here's a small test i have written checking some DOM elements and the current route. Hard to tell without you telling us what your action does.
click('.someSavingButton');
andThen(function() {
assert.equal(currentRouteName(), 'index');
assert.equal(find('.something-new-in-the-dom').length, 1, "New item in HTML");
I stumbled upon this question while also searching for a way to test bubble up actions in an integration test (instead
of closure actions). Maybe you already found a solution, but I will answer to have the next person find it earlier than me.
The idiomatic way to test if an action was called is to write a mock function and assert that it will be called.
In your example - before closure actions - the way to write this kind of test is as follows:
test('it closes the create dialog when close btn is clicked', function(assert) {
// make sure our assertion is actually tested
assert.expect(1);
// bind the action in the current test
this.on('cancelAction', (actual) => {
let expected = { whatever: 'you have expected' };
assert.deepEquals(actual, expected);
// or maybe just an assert.ok(true) - but I am not sure if this is "good" style
});
this.render(hbs`{{group-create cancelCreateAction="cancelAction"}}`)
this.$('button.btn--primary').click()
expect('myAction').to.be.called?
});
Nowadays, with the closure action paradigm, the correct way to bind the mock function would be
// bind the action in the current test
this.set('cancelAction', (actual) => {
let expected = { whatever: 'you have expected' };
assert.deepEquals(actual, expected);
});
this.render(hbs`{{group-create cancelCreateAction=(action cancelAction)}}`)
In my JS view-code I am using a jQuery UI Dialog component to render a popup.
I instantiate it like this:
var popupDialog = $("#myPopupDiv").dialog({
title: "My dialog",
dialogClass: "myDialogClass",
create: createHandler,
draggable: false,
width: width,
height: height,
autoOpen: false
});
Notice it's got autoOpen set to "false". I open it in the "create"-handler:
var createHandler = function(event, ui) {
//Vi venter litt for å sikre at popupen er "klar"
setTimeout(function () {
popupDialog.dialog("open");
}, 5);
};
The open-logic is wrapped in a setTimeout to ensure the popup is ready.
The code works fine in app the browser, but when I run this code using Jasmine test-framework I get an error:
Error: cannot call methods on dialog prior to initialization; attempted to call method 'open'
The test actually passes, so clearly the item is rendered. But I don't like the error showing up when I run the tests!
I suspect that since the Jasmine tests run so fast, the component has not had time to initialize itself. So how can I assure that the component is initialized? I thought putting this logic in the "create"-handler would take care of that since that event is "Triggered when the dialog is created.", but clearly that is not the case.
Here is how I test it:
it("should show my popup", function () {
var myPopupLink = $('.popupLink');
myPopupLink.click();
//Wait until popup is shown
waitsFor(function () {
return !$('.myDialogClass').is(":hidden");
}, "Popupen didn't show", 1000);
//Check that the DOM is as expected
expect($('.myDialogClass .popupContentDiv')).toExist();
expect(...
//Close popup
myPopupLink.click();
expect($('.myDialogClass .popupContentDiv')).not.toExist();
});
Anybody have a clue how I can verify the initialization-status of the popup-dialog?
Or any other workarounds?
Thanks!
The problem with your test is, that it is more an acceptance test then a unit test. Most of stuff that you try to test is functionality of jQueryUi. What you really wanna test is that the createHandler opened the dialog with a delay. So your popupDialog.dialog should be a spy where you can check that it was called after the delay.
At the moment your code is really hard to test cause it is based directly on jquery. You should think about to have functions where you can inject your depenedencies instead of relying on global variables like popupDialog.
Here is an example on how to mock out all dependencies:
//mock out setTimeout so you dont have to wait in your test
jasmine.Clock.useMock();
//create a mock that will return from $().dialog()
var mockDialog = jasmine.createSpy('dialog');
// mock $ to return {dialog: mock that return {dialog: mockDialog}}
var mock$ = spyOn(window, '$').andReturn({
dialog:jasmine.createSpy('$').andReturn({
dialog: mockDialog
})
})
expect(mock$).toHaveBeenCalled();
// call the create function
window[mock$.mostRecentCall.args[0].create]();
jasmine.Clock.tick(4999);
expect(mockDialog$).not.toHaveBeenCalled();
jasmine.Clock.tick(5001);
expect(mockDialog$).toHaveBeenCalledWith('open');
As you can see its very complicated to mock out all the jQuery dependencies. So ether you rewrite your code for better testability or test this stuff as acceptance test with selenium capybara etc.