Mock or spyOn location.reload in angular unit testing - karma-jasmine

I have the function with location.reload(). How to write the angular unit test cases for test that reload functionality.
searchregion(){
location.reload();
}
I tried to written the test cases like below. But it shows error "Error: : could not find an object to spy upon reload()":
it('should test the reload functions', () =>{
spyOn(location, 'reload');
component.searchregion();
expect(location.reload).toHaveBeenCalled();
});
Can anyone please help me on this?

Related

Cypress Spying on Vue components

I'm trying to write an e2e test using Cypress on my Vue app. I want to test if request on form submit returns correct value.
I know i need to use cy.spy. I also know I neet to spy on fetch method but I have no idea which object to tie it to.
From documantation:
The object that has the method to be wrapped.
Which for me would be the component I'm trying to test? I'm not sure if I'm interpreting this argument correctly. Can anyone explain?
EDIT:
My guess is that I need to use methods? But if I try to import them into my test_spec.js I get Cannot find module...
To spy over a response, you can use the route command instead of spy.
https://docs.cypress.io/api/commands/route.html
it('Example Test', function () {
cy.visit('https://stackoverflow.com/');
cy.server(); // cy.server needs to be invoked first in order to use cy.route command
cy.route({
url: `**/your/request/path/**`,
method: 'POST',
onResponse: (xhr) => {
console.log(xhr);
// here you can assert on xhr.response.body values
}
});
});

Detox test failed on typeText if text is "long"

Have some interesting problem with detox testing!
All configs are clearly right (cause in another case it wasn't even work, yeah?)
Work with Mocha tests, and yes, it works.
I use redux to work with state and custom components in my main component.
<OpacityInput
idTest="LoginEmailInput"
icon="account"
placeholder="Login..."
value={this.props.email}
onChangeText={this.emailChanged}
/>
So i pass all data by props to component (testID and value for inputs i pass too)...and here is my test (i make two restricted test to catch an error)
it('should find input login', async () => {
await expect(element(by.id('LoginEmailInput'))).toBeVisible()
})
it('should type text login', async () => {
await element(by.id('LoginEmailInput')).typeText('test#test.com')
})
And it is really interesting...if i want to type 'a'(two-three symbol max) - it is ok! Text passing with no problem! But when i change my 'a' to real e-mail...it crash!
I have a strange feeling that detox has only few seconds for typeText, and if it can't so...it crash :)
Here is the error after crash. I used
detox test —loglevel trace
for details. Test on IOS 6

mocha programmatically set vue error handler

I find myself writing this at the start of pretty much all of my unit tests in mocha:
it('should do something', (done) => {
Vue.config.errorHandler = done;
// do something aynchronous
});
By default, Vue catches all errors itself and logs them to the console, so mocha can't see them. This code makes sure that thrown errors fail the tests.
Is there a way with mocha to do this without having to start every single async test with this line of code? If I have to write / use a plugin, that's fine.
Try:
Vue.config.errorHandler = function (err, vm, info) {
throw err
}
in your test entry.

Ember acceptance test - timeouts

I have a reasonably special use-case:
I have an input field which issues a search when the user has stopped typing for 500ms. This is developed as a reusable add-on.
I would like to write an acceptance test for this but I cannot make the tests pass properly. The first passes, the second doesn't.
Now, the Ember runloop has a nice description but it's behaviour is really "something else".
This is my helper to timeout the runloop:
import Ember from 'ember';
export default Ember.Test.registerAsyncHelper('pauseFor', function (time) {
return Ember.Test.promise(function (resolve) {
Ember.run.later(resolve, time);
});
});
And this is how I use it
it('should do something after 500ms', function () {
visit('/');
fillIn('.search-input', 'a');
pauseFor(500);
andThen(function () {
// do my assertions/expectations here...
});
});
This is the error I get:
The weird thing is that I have 2 test cases and the first passes happily.
I guess my question is:
How to do this properly? What am I missing here or what am I doing wrong? How can I just simply timeout the test case?
Thanks for the halp!

How to set jasmine for karma e2e for testing angular app?

I try to create e2e tests with karma and jasmine with yeoman. In my karma-e2e.conf.js I add jasmine:
files = [
JASMINE,
JASMINE_ADAPTER,
ANGULAR_SCENARIO,
ANGULAR_SCENARIO_ADAPTER,
'test/e2e/**/*.js'
];
A need async testing so I need to use runs, waits, waitsFor (https://github.com/pivotal/jasmine/wiki/Asynchronous-specs)
But if I try to use it:
it('test', function () {
runs(function () {
...
});
});
Scenatio test runner returns this:
TypeError: Cannot call method 'runs' of null
at runs (http://localhost:8080/adapter/lib/jasmine.js:562:32)
at Object.<anonymous> (http://localhost:8080/base/test/e2e/eduUser.js:42:3)
at Object.angular.scenario.SpecRunner.run (http://localhost:8080/adapter/lib/angular-scenario.js:27057:15)
at Object.run (http://localhost:8080/adapter/lib/angular-scenario.js:10169:18)
I don't know where the problem is. Can you help me please?
Angular e2e tests with Karma don't and can't use the JASMINE adapter. Instead you have the ANGULAR_SCENARIO_ADAPTER which has a similar feel to writing Jasmine tests.
All commands in the adapter's API are asynchronous anyway. For example element('#nav-items').count() doesn't return a number, it returns a Future object. Future objects are placed in a queue and executed asynchronously as the runner progresses. To quote the API docs:
expect(future).{matcher}:
[...] All API statements return a future object, which get a value assigned after they are executed.
If you need to run your own asynchronous test code, you can extend the adapter's DSL, this is easier than it might sound. The idea is that you return your own Future which can be evaluated by a matcher such as toBe(). There are some examples on how to do this in the e2e-tests.js Gist from Vojta. Just remember to call done(null, myRetrunValue); when your test code is successful (myRetrunValue is the value evaluated by your matcher). Or done('Your own error message'); if you want the test to fail.
UPDATE: In response to question below. To simulate a login, first add a function called login to the dsl:
angular.scenario.dsl('login', function() {
return function(selector) {
// #param {DOMWindow} appWindow The window object of the iframe (the application)
// #param {jQuery} $document jQuery wrapped document of the application
// #param {function(error, value)} done Callback that should be called when done
// (will basically call the next item in the queuue)
return this.addFutureAction('Logging in', function(appWindow, $document, done) {
// You can do normal jQuery/jqLite stuff here on $document, just call done() when your asynchronous tasks have completed
// Create some kind of listener to handle when your login is complete
$document.one('loginComplete', function(e){
done(null, true);
}).one('loginError', function(e){
done('Login error', false);
});
// Simulate the button click
var loginButton = $document.find(selector || 'button.login');
loginButton.click();
})
};
});
And then call:
beforeEach( function()
{
expect( login('button.login') ).toBeTruthy();
});