Jasmine spyOn function argument object, as Variables are not defined - node.js

I am wiring jasmine test cases for one of the application. I have just started learning jasmine.
Below is my script code
var aclChecker = function(app,config) {
validateResourceAccess = function (req, res, next) {
req.callanotherMethod();
res.send(401,'this is aerror message');
}
}
Now i want to spyOn res and req object to know if send method has been called.
As req and res are not global variables i am having this doubt on how to create a spy on in junit spec
Please help!!!!!!!!

You can simply mock req and res like this.
describe("acl checker", function() {
it("should validate resource access", function() {
var mockReq = {
callAnotherMethod: function() {}
};
var mockRes = {
send: function() {}
};
var mockNext = {};
spyOn(mockReq, "callAnotherMethod");
spyOn(mockRes, "send");
aclChecker.validateResourceAccess(mockReq, mockRes, mockNext);
expect(req.callAnotherMethod).toHaveBeenCalled();
expect(res.send).toHaveBeenCalledWith(401, 'this is aerror message');
});
});

Typically, in a unit test you would mock any resource requests and only validate that the request is proper. So you would instead call a mock request library, and validate that the url and headers are correct.
However, if you really want to test the actual access to the resource, you will need to build your request object first, and give yourself access to it afterwards.
If you want to learn about request mocking, check out jasmine-ajax:
https://github.com/pivotal/jasmine-ajax
If you still want to do this, you should use a beforeEach function in the test file to create the dependencies you need for your tests.
Take a look at this for more help with beforeEach:
https://github.com/pivotal/jasmine/wiki/Before-and-After

Related

How to do callback in our component using react jest test cases

How can we do callback on success and failue cases for below lines of code for test coverage using jest
const handleService = () => {
window.domain.service("1321",'',onSuccess, onFailure)
}
const onSuccess = () => {
....update state values
}
const onFailure = () => {
....update state values
}
Something like this:
Spy on window.domain.service to gain access to the calls it receives. This will allow you to access the parameters of those calls which will be "1321",'',onSuccess, onFailure
Assign the function you wish to test to a variable
Invoke the function to execute the code in it (this will get you the coverage)
(Optional) assert that the callback functions behave correctly
Here is a snippet to help demonstrate
it('should run', () => {
// Some setup to create the function on the window, may not be needed if done elsewhere.
// Could be good to do this in a beforeEach and clean up in afterEach to avoid contaminating the window object
window.domain = {
service: () => {},
}
// Spy on the window.domain.service method.
// Provide a mock implementation if you don't want the real one to be called
const serviceSpy = jest.spyOn(window.domain, 'service');
executeYourCode();
// capture the arguments to the call
const [_arg1, _arg2, onSuccess, onFailure] = serviceSpy.mock.calls[0];
// execute the callbacks
onSuccess();
onFailure();
});

Jest with fetch-mock generating error: TypeError: Cannot read property 'prototype' of undefined when using on nodejs

I'm almost sure it's my mistake, but I spent one entire day trying to solve and I've being failed 😞.
I'm trying to configure the fetch-mock on node to use with jest. I tried a lot of things and the best result that I have is this:
https://user-images.githubusercontent.com/824198/50566568-7b49e400-0d22-11e9-884f-89720899de3a.png
I'm sure my mock is working because if I pass it through parameter to the "Myclass.query" it works perfectly.
I'm also sure that the mock is arriving in my test file, because the mock function is present in the fetch module.
But... all together aren't working 😭.
I created a very simple and small project to see this problem happening:
https://github.com/cesarjr/test-node-fetch
Can anyone help me?
Jest uses the mock at __mocks__/node-fetch.js any time node-fetch is required during the test.
The problem is that the first thing fetch-mock does is require node-fetch.
This means that Request is not defined when it is set on the config here, so calling prototype on the undefined Request causes an error here.
Someone smarter than me might know how to force Jest to require the actual node-fetch when fetch-mock requires node-fetch in the mock for node-fetch, but from what I can see it doesn't look like it is possible.
Looks like you will have to delete the mock at __mocks__/node-fetch.js and pass fetch to your code, something like this:
myclass.js
class MyClass {
static query(fetch, sessionId, query) {
const url = 'https://api.foobar.com';
const body = {
sessionId,
query
};
return fetch(url, {
method: 'post',
body: JSON.stringify(body)
})
.then(res => res.json());
}
}
module.exports = MyClass;
...then create the sandbox in your test and pass it to your code, something like this:
myclass.test.js
const fetch = require('fetch-mock').sandbox();
const MyClass = require('./myclass');
describe('MyClass', () => {
describe('.query', () => {
it('returns the response', () => {
fetch.mock('*', {'result': {'fulfillment': {'speech': 'The answer'}}});
expect.assertions(1);
return MyClass.query(fetch, '123', 'the question').then((data) => {
expect(data.result.fulfillment.speech).toBe('The answer'); // SUCCESS
});
});
});
});
I've now found a reliable way to combine fetch-mock and jest http://www.wheresrhys.co.uk/fetch-mock/#usageusage-with-jest

How can I Mock node-rest-client request?

I'm using node-rest-client for my project and I've come to the point where I want to start unit testing my classes that utilize node-rest-client. Is there any examples on how I can mock the Client in my tests? I am using Sinon in my unit testing.
Step 1: In the js code you are testing, export the node-rest-client instance so it can be available to your test code. For example in myApp.js, I put this:
var Client = require('node-rest-client').Client;
var restClient = new Client();
exports.restClient = restClient; //instance now available outside this module
restClient.get(someUrl, ...); //actual node rest client call
Step 2: In your test code, create a wrapper function that returns a fake function, and use sinon to mock it into your target code. This allows you to inject the return data and response code during your test setup.
var nodeRestGet = function (data, statusCode) {
return function (url, cb) {
cb(data, { statusCode: statusCode || 200 });
}
};
sinon.stub(myApp.restClient, 'get').callsFake(nodeRestGet("", 200));
Step 3: Write your test code. Note that you might want to restore the method (remove the mock) if you are running multiple tests:
myApp.doThings(); // TEST
myApp.restClient.get.restore(); // removes the mock

Stub/mock process.platform sinon

I am working with process.platform and want to stub that string value to fake different OSes.
(this object is generated out of my reach, and I need to test against different values it can take on)
Is it possible to stub/fake this value?
I have tried the following without any luck:
stub = sinon.stub(process, "platform").returns("something")
I get the error TypeError: Attempted to wrap string property platform as function
The same thing happens if I try to use a mock like this:
mock = sinon.mock(process);
mock.expects("platform").returns("something");
You don't need Sinon to accomplish what you need. Although the process.platform process is not writable, it is configurable. So, you can temporarily redefine it and simply restore it when you're done testing.
Here's how I would do it:
var assert = require('assert');
describe('changing process.platform', function() {
before(function() {
// save original process.platform
this.originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform');
// redefine process.platform
Object.defineProperty(process, 'platform', {
value: 'any-platform'
});
});
after(function() {
// restore original process.platfork
Object.defineProperty(process, 'platform', this.originalPlatform);
});
it('should have any-platform', function() {
assert.equal(process.platform, 'any-platform');
});
});
sinon's stub supports a "value" function to set the new value for a stub now:
sinon.stub(process, 'platform').value('ANOTHER_OS');
...
sinon.restore() // when you finish the mocking
For details please check from https://sinonjs.org/releases/latest/stubs/

Unit testing unavailable global function (couchapp, mocha)

I'm trying to unit test a CouchDB design doc (written using couchapp.js), example:
var ddoc = {
_id: '_design/example',
views: {
example: {
map: function(doc) {
emit(doc.owner.id, contact);
}
}
}
}
module.exports = contacts
I can then require this file into a mocha test very easily.
The problem is CouchDB exposes a few global functions that the map functions use ("emit" function above) which are unavailable outside of CouchDB (i.e. in these unit tests).
I attempted to declare a global function in each test, for example:
var ddoc = require('../example.js')
describe('views', function() {
describe('example', function() {
it('should return the id and same doc', function() {
var doc = {
owner: {
id: 'a123456789'
}
}
// Globally-scoped mocks of unavailable couchdb 'emit' function
emit = function(id, doc) {
assert.equal(contact.owner.id, id);
assert.equal(contact, doc);
}
ddoc.views.example.map(doc);
})
})
})
But Mocha fails with complaints of global leak.
All of this together started to "smells wrong", so wondering if there's better/simpler approach via any libraries, even outside of Mocha?
Basically I'd like to make mock implementations available per test which I can call asserts from.
Any ideas?
I'd use sinon to stub and spy the tests. http://sinonjs.org/ and https://github.com/domenic/sinon-chai
Globals are well, undesirable but hard to eliminate. I'm doing some jQuery related testing right now and have to use --globals window,document,navigator,jQuery,$ at the end of my mocha command line so... yeah.
You aren't testing CouchDb's emit, so you should stub it since a) you assume that it works and b) you know what it will return
global.emit = sinon.stub().returns(42);
// run your tests etc
// assert that the emit was called
This part of the sinon docs might be helpful:
it("makes a GET request for todo items", function () {
sinon.stub(jQuery, "ajax");
getTodos(42, sinon.spy());
assert(jQuery.ajax.calledWithMatch({ url: "/todo/42/items" }));
});
Hope that helps.

Resources