Qunit test fail in async call - qunit

example :
test("An async test", function(){
stop();
expect(1);
model.save( {} , {
success : function(model,resp){
ok(model.get('id') != null, "Got id");
start();
}
});
});
it gives me an error
Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.

Could this be because your ajax call throws an error?
If it did, it would never "succeed" and do an assertion, and it would never call start().
I suggest moving your assertion and your start() to a "complete" block instead. Complete is ALWAYS called, if the ajax was successful or in error.
Alternatively you could register an assertion and a start() in an "error" block

Related

How to apply condition in cypress intercept

When I do cy.intercept("URL"), it returns me 409-conflict error ,
My target is to call a function upon 409 error .
How to achieve conditional intercept ,or how can I check in cy.intercept(URL) returns http status as 409, if so I want to call a function (). want to achieve something like the below , how to do so in cypress ?
if(cy.intercept(url(.getHttpStatus==409){
//function call
}
The Cypress team recommends avoiding conditional testing. For a negative test case, you should take the steps to have the URL return a 409 response. With that you will need to the following, to tell Cypress you are expecting a status code other than 2xx or 3xx:
cy.intercept({
url: "URL",
failOnStatusCode: false
})
The conditional statement goes inside the callback, docs are here
cy.intercept(URL, (req) => {
req.continue((res) => {
if (res.statusCode == 409) {
// function call
}
})
})

Angular 8 patch request httpclient.subscribe() doesnt hit response, err or ()

I am encountering an issue I do not understand.
Inside one service I have the following code.
when the code hits PATCH LINE, it jumps immediately to RETURN NOTHING LINE.
the catchError line is not hit.
the () line is not hit
the err line is not hit.
I have compared this to working services and I do not see any difference.
patchItem(item_: Project): Observable<Project> {
const url: string = `${this.serviceUrl}/${item_.id}`;
const data = JSON.stringify(item_);
console.log('inside patch item');
console.log(url);
this.http.patch(url, data, httpOptions) //PATCH LINE
.pipe(
catchError(err => this.handleError('PatchItem', err))
)
.subscribe((response) => {
console.log('item patched ');
return this.myResponse.push(response);
}
, err => console.log("inline error encountered")
,() => console.log("this seems to have completed")
);
console.log("return nothing"); //RETURN NOTHING LINE
return null;
}
The API is C# webapi 2
It is being hit.
There is a problem though, I am expecting the JSON to be passed in and webForm_ is always NULL.
This is probably an important clue.
Again, i compare this to working calls and can not find a difference.
When I inspect the variable in jquery, it has the correct value.
In postman, i get the expected response.
[System.Web.Http.HttpPatch]
[Route("{itemId_}")]
public IHttpActionResult PatchById([FromUri] int itemId_, [FromBody] Models.mpgProject webForm_)
{
return JSONStringResultExtension.JSONString(this, "foobar for now", HttpStatusCode.OK);
}
To save a cycle, here is the handleError function.
I have copy/pasted this from a service that is working as expected.
protected handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error); // log to console instead
console.log(`${operation} failed: ${error.message}`);
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
How can Angular be skipping all the subscription stuff when it IS actually calling the API?
I think it has to be a simple syntax issue, but I have been staring at it for hours... :-(
Happy to post any other code requested...
tyia
ps - I would also be happy to retitle the question. I am at a loss for how to phrase a good question title for this...
Your handleError method returns a function (that returns an Observable) when it should return an Observable.
It looks as if the error handler you copied from another service does not fit here.
I could imagine an error handler like this:
private handleError<T>(operation = "operation", error: HttpErrorResponse) {
console.error(error); // log to console instead
console.log(`${operation} failed: ${error.message}`);
// Let the app keep running by returning an empty result.
return of({} as T);
}
This method returns an Observable of an empty object. However, this might not be the best option to react on a failing HTTP PATCH request. You would better throw that error up to the component and let the user retry.

Error handling using the catch block in cypress

I'm trying to handle an error in Cypress but the Cypress app is throwing error
cy.get('button[name="continue"]',{timeout: 30000})
.catch((err) => {
cy.console.log("error caught");
})
The error I get:
TypeError: cy.get(...).catch is not a function
tl;dr
Cypress has no .catch command the error message clearly states that.
Exception handling in Cypress
The documentation on error recovery clearly states:
The following code is not valid, you cannot add error handling to Cypress commands. The code is just for demonstration purposes.
cy.get('button').contains('hello')
.catch((err) => {
// oh no the button wasn't found
// (or something else failed)
cy.get('somethingElse').click()
})
They deliberately left this out and in the docs they explain it in great length why you shouldn't be able to do it.
If you really want, you can catch uncaught exceptions, just try the suggestions of the Catalog of Events on this matter:
it('is doing something very important', function (done) {
// this event will automatically be unbound when this
// test ends because it's attached to 'cy'
cy.on('uncaught:exception', (err, runnable) => {
expect(err.message).to.include('something about the error')
// using mocha's async done callback to finish
// this test so we prove that an uncaught exception
// was thrown
done()
// return false to prevent the error from
// failing this test
return false
})
// assume this causes an error
cy.get('button').click()
})

Changing message for timeout using Jasmine done

For now I have the following code...
it("takes a long time", function(done) {});
Problem is when it times out I get the following message...
Error: Timeout - Async callback was not invoked within timeout
specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Can I change this message to something more specific?
That is an error regarding your test, not an error of the code you're testing. If your test is properly written, you shouldn't encounter that error. The test itself is timing out. If you're writing a test to see how/whether some code times out, you would write the test to handle that, rather than the test just throwing an error because you didn't call done() in time.
// this function times out if passed "true" as second argument
function testThis(done, shouldTimeout) {
setTimeout(function() {
shouldTimeout || done();
}, 500);
}
it("timed out", function(done) {
var timedOut = false;
setTimeout(function() {
testThis(function() {
// this shouldn't be called because we're telling `testThis` to timeout
timedOut = true;
}. true);
});
setTimeout(function() {
expect(timedOut).toBeFalsy();
done();
}, 505);
});
If you needed to wait a long time to see if something times out, you can change how long Jasmine will wait before a test throws a timeout error by changing jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
Jasmine does have a mock for setInterval and setTimeout that let you run that code synchronously, and saves all that wasted time waiting.

Is it possible to continue after a fail in a chain?

I have something like:
doHTTPRequest()
.then(handleSuccess, checkNotFound)
.then(uploadSomething)
.fail()
.done()
Now when I'm getting into checkNotFound I need to check if I got 404, if so it's not an actual fail and I want to continue with uploadSomething, but Q chaining directs me to fail.
On any other failure (e.g: any other status code) I do want to get into fail().
The signature of then is promise.then(onFulfilled, onRejected) and it returns a new promise. The returned promises is resolved by whatever onFulfilled or onRejected returns or throws. That is to say, if you handle the error in onRejected and return a promise that fulfills, that will pass through to the result and skip your fail handler. In code:
function request(url) {
// returns a promise
}
function retryForeverLoop(url) {
return request(url).then(null, function (error) {
return retryForeverLoop(url);
});
// note that retrying forever might not work out well
}
retryForeverLoop(url)
.then(uploadSomething)
.done()
This could work if the library errbacks with the request object.
doHTTPRequest()
.fail(function(request){
if( request.isRequest && request.is404 ) {
//This will propagate to the next .then
return request;
}
else {
//This will propagate to the next .fail
throw request;
}
})
.then(handleSuccess)
.then(uploadSomething)
.fail()
.done()
Btw the second argument to .then is almost entirely about promise library interop. In user code you should use the usually available, far more readable .catch/.fail/.whatever alternative which also avoids the pitfall mentioned here https://github.com/kriskowal/q/#handling-errors. If such alternative is not available, even then .then(null, handler) should be used instead of passing error and success in a same .then call.
The sync equivalent of above code is like:
try {
try {
var a = doHTTPRequest();
}
catch(request) {
if( request.isRequest && request.is404 ) {
a = request;
}
else {
throw request;
}
}
uploadSomething(handleSuccess(a));
}
catch( e ) {
//This is the second .fail()
}

Resources