I need some help.
This is fragment of my code, i can't return boolean from it("present or not")
, so everything is working incorrectly. where I was mistaken?
describe("first TEST", function () {
var boolean, parsingAllProfiles, getRandomProfile, randomProfile;
it("present or not", function () {
freelan.notFreelancersFound.isPresent().then(function (result) {
**return boolean = result;**
})
})
if (boolean) {
console.log("NOTHING!!!!!")
} else {
it("array of profiles", function() {
Promise.resolve(freelan.parsingAllProfilePage()).then(function (profiles) {
var arrForCheck = freelan.cloneArray(profiles);
freelan.checkKeywordInProfile(arrForCheck, params.keyword);
return randomProfile = profiles[Math.floor(Math.random() * profiles.length)];
})
});
}
});
I'm not sure exactly what you are trying to do with the boolean, but here's what it might look like in a test with chained promises.
describe("first TEST", function () {
var boolean, parsingAllProfiles, getRandomProfile, randomProfile;
it("present or not", function () {
freelan.notFreelancersFound.isPresent().then(function(result) {
if (result) {
freelan.parsingAllProfilePage().then(function(profiles) {
var arrForCheck = freelan.cloneArray(profiles);
expect(freelan.checkKeywordInProfile(arrForCheck, params.keyword).toBe(true);
});
} else {
console.log("NOTHING!!!!!");
}
});
});
});
I don't know the library in question, but promise-based code async, meaning that this inner code **return boolean = result;** won't run until after other things in the main function.
it("present or not", function () {
freelan.notFreelancersFound.isPresent().then(function (result) {
**return boolean = result;**
})
})
What you really need to do is read up on Promises and learn how to chain then. If you return a promise from your test, it will wait for that promise to resolve before moving onto the next test.
Related
I have defined a function as following :
function getCurrentComponent(){
if($rootRouter._currentInstruction){
return $rootRouter.recognize($rootRouter._currentInstruction.urlPath).then(function (data) {
return data.component.componentType;
});
}else{
return null;
}
}
To call this function I did as following :
factory.getCurrentComponent().then(function (data) {
...
});
The problem is when the getCurrentComponent function returns a null value, the following error is generated :
Cannot read property 'then' of null
How can I solve this ?
Edit:
I forgot to say that I'm limited to use ES5, so I can't work with the object Promise
Use Promise.reject() function.
function getCurrentComponent() {
if ($rootRouter._currentInstruction) {
return $rootRouter.recognize($rootRouter._currentInstruction.urlPath).then(function(data) {
return data.component.componentType;
});
} else {
return Promise.reject('_currentInstruction is fale');
}
}
factory.getCurrentComponent().then(function(data) {
...
}).catch(function(e) {
console.log(e); // Output: _currentInstruction is fale
});
Resource
Promise.reject()
If you're unable to use Promise you can return an object with a function then.
function getCurrentComponent() {
if ($rootRouter._currentInstruction) {
return $rootRouter.recognize($rootRouter._currentInstruction.urlPath).then(function(data) {
return data.component.componentType;
});
} else {
var helperThen = { then: function(fn) { fn(null) } };
return helperThen;
}
}
factory.getCurrentComponent().then(function(data) {
// Check if data is null.
...
});
I cant use the object Promise in ES5.
Use the AngularJS $q Service:
function getCurrentComponent(){
if($rootRouter._currentInstruction){
return $rootRouter.recognize($rootRouter._currentInstruction.urlPath).then(function (data) {
return data.component.componentType;
});
}else{
̶r̶e̶t̶u̶r̶n̶ ̶n̶u̶l̶l̶;̶
return $q.reject(null);
}
}
AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc.
The $q Service is a Promises/A+-compliant implementation of promises/deferred objects thst is integrated with the AngularJS framework and its digest cycle.
Convert the function to use a Promise.
function getCurrentComponent(){
return new Promise((resolve, reject)=>{
if($rootRouter._currentInstruction){
resolve( $rootRouter.recognize($rootRouter._currentInstruction.urlPath).then(function (data) {
return data.component.componentType;
}));
} else{
reject(null);
})
}
Now you can check resolve and reject with then() function,
factory.getCurrentComponent().then(function (resolved) {
//handle success here
}, function(rejected) {
// handle rejection here
});
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
When i created this question, my doubt was about how would i be able to test an asynchronous request utilizing mocha/enzyme/chai/sinon.
I am sure that there are different ways, but a possible one is to mock it with a handmade function that returns the appropriate values (check the answer for details).
My getInitialState method is this:
getInitialState: function() {
var me = this;
var documentData = null;
var promise = me.getDocuments();
promise.then(function(value) {
var documents = value.map(function(obj) {
return Object.keys(obj).sort().map(function(key) {
return obj[key];
});
});
documentData = documents;
});
return ({
cd: false
});
},
And the getDocuments() function that returns a promise is this:
getDocuments: function() {
var deferred = when.defer();
Collection.fetch({cd: workspaceInfo.getCD()}).then(
function(results) {
deferred.resolve(results);
},
deferred.reject
);
return deferred.promise;
},
How can i successfuly test it?
Would i have to mock the getInitialState method itself? (is that even possible)
Or just the getDocuments function with some predictable return values?
Thanks in advance, any help will be appreciated.
I solved this by requiring the Collection (which is a rest API that brings some values from a database)
var Collection = require("path/to/my/collection/Collection");
Afterwards, i use it in my getDefaultProps() method:
getDefaultProps() {
return {
Collection: new Collection()
};
},
And this in turn enables me to write tests that initialize a mocked Collection (fileDataResponse is a JSON with some data):
var CollectionMock= {
fetch: () => {
return {
then: callback => callback(fileDataResponse)
};
}
};
And use it in my test afterwards:
it("should open the modal without a loaded configuration", function() {
var instance, wrapper;
wrapper = mount(
<DocumentPreview
Collection={CollectionMock}/>
);
instance = wrapper.component.getInstance();
instance.openModal();
expect(wrapper.find('#MockedTest' + 'docOid251085').exists()).to.equal(true);
wrapper.unmount();
});
I wonder to know the best way of binding result of a promise which is as an injection to html tag using angular 2(I use ionic 2)...
As you know the main problem with async coding is loosing reference to the current object. It seems I should pass current object as a prameter to Promise function generator.
I searched internet for better solution but nothing I found! So is there any better approch?
Ionic 2 itself use observation and subscribe to do async proccess. But the major problem is that for existing functions which are not observable it couldn't work!
My approch:
Injectable class:
export class PromiseComponent {
doPromise = function (obj: any) {
return new Promise(function (resolve2) {
setTimeout(function () {
resolve2({ num: 3113, obj: obj });
}, 5000);
});
}
}
Call on click:
promiseVal = 0
doMyPromise() {
this.myPromise.doPromise(this).then(this.secondFunc);//UPDATED HERE
}
//UPDATED HERE
secondFunc = function (res) {
this.promiseVal = res.num
}
Html:
<div>{{promiseVal}} </div>
<button (click)="doMyPromise()">Do Promise</button>
If you want to consume a promise inside your component:
promiseVal = 0
doMyPromise() {
this.myPromise.doPromise().then((res) => {
this.promiseVal = res.num
});
}
And I don't know the reasoning behind your Service but it usually is like this (optional):
export class PromiseComponent {
doPromise() { //This method will return a promise
return new Promise(function (resolve2) {
setTimeout(function () {
resolve2({ num: 3113, obj: obj });
}, 5000);
});
}
}
After OP edited the post:
You can change this:
doMyPromise() {
this.myPromise.doPromise(this).then(this.secondFunc);//UPDATED HERE
}
to
doMyPromise() {
this.myPromise.doPromise(this).then(this.secondFunc.bind(this));//UPDATED HERE
}
As you know the main problem with async coding is losing reference to the current object
That's not true, the arrow function does not bind its own this therefore you don't need to send this to doPromise
export class PromiseComponent {
doPromise () {
return new Promise(function (resolve) {
setTimeout(function () {
resolve({ num: 3113 })
}, 5000)
})
}
}
promiseVal = 0
doMyPromise() {
this.myPromise.doPromise()
.then(res => {
this.promiseVal = res.num
})
}
I am writing a Jasmine custom matcher to use in a Protractor spec and I want to check that the browser title is equal to some string. I am unable to get this code to work properly and after spending hours debugging it, I can only assume that the browser object is not being accessed inside the matcher function as I expect it to be. When I modify the matcher function to accept browse.getTitle() as the actual argument then it works fine, which leads me to my assumption. Can anyone find the issue here and explain it to me?
beforeEach(function() {
jasmine.addMatchers({
toBeOnPage: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
var result = {};
result.pass = actual.getTitle() === expected.title;
return result;
}
};
}
});
});
var homepage = { url: 'Homepage URL', title: 'Homepage Title' };
describe('regression:', function() {
it('homepage loads successfully', function() {
browser.get('http://localhost/#/home');
expect(browser).toBeOnPage(homepage);
});
});
The problem is that getTitle() returns a promise. Resolve it:
beforeEach(function() {
jasmine.addMatchers({
toBeOnPage: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
return {
pass: actual.getTitle().then(function (title) {
return title === expected.title;
});
};
}
};
}
});
});
I am attempting to use Typeahead with my SignalR implementation.
What is happening is my Hub is getting hit and returning the value, but my result after .done() is undifined. I cannot work out why?
Javascript
$(function () {
var search = $.connection.searchHub;
$.connection.hub.start().done(function () {
$('#searchBar').typeahead(null, {
minLength: 2,
// begin source
source: function (query, process) {
var suggestions = [];// my callback value
search.server.search(query)
.done(function (result) {
console.log(result);
$.each(result, function () {
console.log(result);
suggestions.push(this);
process(suggestions);//process is a callback method
});
}).fail(function (error) {
console.log(error);
process([]);//process is a callback method, don't know if this is necessary here, but will produce no suggestions
});
}
});
});
Hub:
[HubName("searchHub")]
public class SearchHub : Hub
{
public async Task Search(string query)
{
api = new MovieApi();
var result = await api.Search(query);
if (result.results != null)
{
Clients.Client(Context.ConnectionId).results(result.results[0].title);
}
else
{
Clients.Client(Context.ConnectionId).noResults("There are no search results!");
}
}
}
Your search method does not return anything so its not strange that its undefined. You need to change to Task<T> and return something
Also I can not see that you are subscribing to results or noResults? Like
search.client.results = function(result) {
console.log(result);
};
edit: Also its very strange to use SIgnalR for this, standard REST with request/response should be fine here