Mocha Chai - Test multiple properties of object - mocha.js

I want to check if my response object contains mentioned properties using chai should assertion.
Below is my code snippet:
chai.request(app)
.post('/api/signup')
.send(
data
)
.then(function (response) {
response.should.have.status(200);
response.body.should.have.property('active', 'mobileNumber', 'countryCode', 'username', 'email', 'id', 'createdAt', 'updatedAt', 'location');
done();
})
.catch(function (error) {
done(error);
})
But I am getting below error:

Found how to achieve it using mocha chai-should,
Function name is .should.have.keys()
Just pass the properties to this function and it will check they should be present in the object you are testing.
bellow is the code
response.body.should.have.keys('active', 'mobileNumber', 'countryCode', 'username', 'email', 'id', 'organisationId', 'createdAt', 'updatedAt', 'location');

If you're exclusively utilising Chai (in Postman, for example), the following string of functions will successfully aid you:
response.body.to.include.all.keys("active", "mobileNumber");
The full list of API's (including an example of the above) can be found here.

Related

cypress intercept url response using cypress-cucumber not returning response

This is an example of my cucumber when statement
basic-interaction.js
let aliasHref = 'aliasHref';
import {Given, When, Then} from 'cypress-cucumber-preprocessor/steps';
When(/I click link \'([^\']+)\'/, async (strSelector) => {
cy.get(strSelector).should('have.attr', 'href').then(href => {
cy.intercept(href).as(aliasHref);
});
cy.get(strSelector).click();
});
Then(/I redirect to url \'([^\']+)\'/, (strUrl) => {
cy.wait(`#${aliasHref}`).its('request.url').should('eq', strUrl); // This passes
cy.wait(`#${aliasHref}`).should('have.property', 'response.statusCode', 200); // This fails
// cy.wait(`#${aliasHref}`).should('have.property', 'status', 200); // This fails
});
I keep getting error
AssertionError: expected { Object (id, routeHandlerId, ...) } to have property 'response.statusCode'
or
AssertionError: expected { Object (id, routeHandlerId, ...) } to have property 'status'
Please try cy.wait(`#${aliasHref}`).its('response.statusCode').should('eq', 200).

Mocha Chai check if Json response contains specific property

I'm creating API test which checks that the response contains specific key "textId" in structure:
it('TC-4 /rest/passwords/ should change "password"', function() {
return chai.request(serverurl)
.post('/rest/passwords/')
.set('Content-Type', 'application/json')
.set('Accept', 'text/html')
.set('X-Api-Key', global.apikey)
.set('Cookie', global.cookie)
.send({password: "password"})
.then(function(res) {
res.should.have.status(200);
res.should.be.json;
console.log('TC-4 /rest/passwords/: %j\n', res.body);
res.body.should.have.all.keys(['textId']);
});
});
response is following:
[{"textId":"PasswordNeedsAtLeastOneDigit","parameters":{}},{"textId":"PasswordNeedsAtLeastOneUpperCaseCharacter","parameters":{}}]
I tried:
res.body.should.have.property('textId');
res.body.should.have.nested.property('textId');
res.body.should.have.all.keys(['textId']);
res.body.should.have.all.nested.keys(['textId']);
none of them works
It's a bit late but for any future viewers, you need something like this:
res.body.should.have.property('data').that.includes.all.keys(['status', 'id', 'name', 'email',
'bio', 'image', 'email_verified', 'role', 'isActive', 'isDeleted', 'createdAt', 'updatedAt', 'token']);

How will write jasmine to cover my function? I am getting error "config method in not exist"

Getting error to my function which I am trying to cover in Jasmine
"Error is config method does not exist" And config the method which I am trying to cover.
I am expecting to cover the right test case scenario to my config method.
const config = () => {
return ({
name: 'modal.name',
class: 'modal.class',
choice: 'modal.choice'
});
}
describe('Config', () => {
it('config is defined', () => {
let data = {
name: 'modal.name',
class: 'modal.class',
choice: 'modal.choice'
};
Object.assign(config, data);
spyOn(data, 'config').and.returnValue(Promise.resolve(data));
});
});
You are getting that error because you are trying to spy the config method in your data object with the statement:
spyOn(data, 'config').and.returnValue(Promise.resolve(data));
The data object has no config method so, when you call spyOn it throws that error.
Your it says that you are trying to test that config is defined, but you are doing really strange things in your test. If you want to check that config is defined you could do:
it('config is defined', () => {
expect(config).toBeDefined();
});
A more elaborated test would be to test that the method, besides existing, returns the data you want:
it('config returns the configuration', () => {
expect(config()).toEqual({
name: 'modal.name',
class: 'modal.class',
choice: 'modal.choice'
});
});

How to skip support/index.js for certain spec files in Cypress

Is it possible to skip the beforeEach function in my Cypress index.js support file, for a certain spec file (access.spec.js)?
index.js
// This example support/index.js is processed and
// loaded automatically before your test files.
beforeEach(function () {
cy.request('POST', 'https://exampleURL.com', {
email: 'email',
password: 'password'
}).then((response) => {
cy.setCookie('accessToken', response.body.AccessToken);
});
cy.setCookie('email', 'email');
cy.setCookie('environment', '3');
cy.setCookie('name', 'name');
}
access.spec.js
it("it should send user back to login screen when AccessToken is missing", () => {
// Code here
});
From a conventional perspective, a beforeEach block in support/index.js should only have code that applies to all test specs. If logic only pertains to some tests and not to others, it should not be placed in support/index.js.
Trying to override how Cypress intends to use support/index.js is working against the framework, and not with it.
Subsequently, an alternative to duplicating this beforeEach logic in all tests that require it, would be to create a Custom Command, like this:
Cypress.Commands.add('login', () => {
cy.request('POST', 'https://exampleURL.com', {
email: 'email',
password: 'password'
}).then((response) => {
cy.setCookie('accessToken', response.body.AccessToken);
});
cy.setCookie('email', 'email');
cy.setCookie('environment', '3');
cy.setCookie('name', 'name');
})
...and then, from within the specs that require this functionality, you could have a simpler beforeEach block, like this:
beforeEach(function() {
cy.login();
});
However, given that your access.spec.js test is concerned with a missing accessToken, you would not use the beforeEach block in that particular test. Instead, copy the login code into that test, and use cy.route instead of cy.request (which hits your actual endpoint), so that you can stub out a response that does not return an accessToken.

Testing a method that is subscribed to an observable - Angular 2

I want to test a method inside of an Angular 2 component that is subscribed to an observable that is returned from a method in a service. Here is the code for the service method in summary:
public create(user: User): Observable<any> {
return this.http.post(this._api.create,
JSON.stringify(user), {
headers: this.apiConfig.getApiHeaders()
}).map((res: Response) => res.json());
}
It's easy to unit test this method because it returns an observable so I can just subscribe to it. But I want to test the method in the component that is already subscribed to this:
public onSubmit(user: User): void {
this._authentication.create(user).subscribe((token) => {
localStorage.setItem('token', token);
this.router.navigate(['/Home']);
});
}
Heres my spec so far but when I try to spyOn the localStorage.setItem it comes back as not being called. My understanding is it's probably checking to see if it's been called before it's actually been called.
it('Should login a user and on success store a token in localStorage',
injectAsync([TestComponentBuilder], (tcb) => {
return tcb.createAsync(Login).then((fixture) => {
let instance = fixture.debugElement.componentInstance;
localStorage.clear();
spyOn(localStorage, 'setItem');
instance.onSubmit({userId: 'some#email.com', password: 'password', siteName: 'sample'});
expect(localStorage.setItem).toHaveBeenCalled();
});
})
);
I'm wondering if I need to mock out the this._authentication.create method to return a new observable with a mock response in it?
After more research a few articles indicated that I do need to mock out the service and return an Observable.of() which runs synchronously to solve the problem, ill copy the code below. This however still doesn't work, I've been working on this most of the day, I don't feel this should be that hard, any help appreciated.
class MockAuthentication extends Authentication {
public create(user: Object): Observable<any> {
return Observable.of({'test': 'test'});
}
}
Ok so it's taken me most of the day but I finally cracked it. Instead of using the injectAsync and TestComponentBuilder to set up the spec I just need to use inject and inject the component in just like you do a service. This seems fine because I don't need to test anything in the view like events.
Heres the final spec that does work:
it('Should set token in localStorage, set the new user,
and navigate to home page on succesful login',
inject([Login], (login) => {
login.router.config([ { path: '/', name: 'Home', component: Home }]);
spyOn(localStorage, 'setItem');
spyOn(login._currentUser, 'set');
spyOn(login.router, 'navigate');
login.onSubmit({ userId: 'some#email.com', password: 'password', siteName: 'sample' });
expect(localStorage.setItem).toHaveBeenCalledWith('token', 'newToken');
expect(login._currentUser.set).toHaveBeenCalledWith({ 'test': 'one' });
expect(login.router.navigate).toHaveBeenCalledWith(['/Home']);
}));
Hope this might help someone in the future.
I guess you want to inject a mock Router instance to your component and then after navigate(['/Home']) was called on the mock Router, you check if localStorage.setItem(...) was called.
See my gist here.
Basically you can do several things here. First of all, stub your http call (I'm guessing from a service) with a simple observable response of the token (or other response) you want.
service.stub.ts
export class MyStub {
public create(user: User): Observable<User> {
return Observable.of('insert test token here');
}
// other stubbed methods ...
}
And then inside your test:
myComp.spec.ts
let comp: MyComponent;
let fixture: ComponentFixture<MyComponent>;
let sst: ServiceStub;
describe('MyComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyComponent],
schemas: [NO_ERRORS_SCHEMA]
}).overrideComponent(OnboardFacilityNewComponent, {
set: {
providers: [
{ provide: MyService, useClass: ServiceStub },
]
}
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(MyComponent);
comp = fixture.componentInstance;
st = fixture.debugElement.injector.get(MyService);
});
}));
it('should submit new onboardFacility', fakeAsync(() => {
const sst = spyOn(sst, 'create').and.returnValue(
Observable.of('some token here')
);
comp.onSubmit(testUser);
fixture.detectChanges();
expect(comp.token).toEqual('some token here');
expect(spy.calls.any()).toEqual(true);
}));
});
Here, you can simply replace actual data with test data to test the behavior of your testing, rather then your testbed, your services, localStorage, etc. Obviously the test I wrote here assumes you would store the token returned from your service in your component, rather then localStorage (though there is a way to do that), but I'm just simply to show the concept rather then your specific use case.
In your use case you'll also need to the stub the router, which you can learn how to do here.

Resources