I have a function say MyFunction(arg) which I have mocked.
Inside the function, another function is called and the result of the second function is assigned to a local variable(say myVar) declared inside MyFunction(arg).
Can I use mockito anyway to fetch the value of myVar in my test function?
Adding code :
OrderOperations.java
public OrderResponse createOrder(Orders order){
OrderResponse orderResponse = new OrderResponse();
ManipulatedOrder = partnerOrder;
partnerOrder = parseXML(order) //This function manipulates the details of order object and gives back the result.
String xmlRequest = xs.toXML(partnerOrder); //The response is converted to XML
//Few modifications are done to the xmlRequest and then it is sent to another function
orderResponse = invokeAPI(xmlRequest); //This function uses the xmlRequest.
return orderResponse;
}
I want to test this function using JUNIT, mock this function and in someway want to capture what is being sent to invokeAPI if I pass test values to the Orders object.
Related
The code works like this
let getToken = await apiCall();
apiCall() calls a few internal functions and populates getToken variable with a token. The problem is, in my tests, I can't seem to populate that variable with anything. It is always undefined and an error gets thrown. Is there any way to populate this variable with a dummy value in a unit test?
EDIT
constructor() {
this._token = '';
}
I want to inject a value in token via a unit test. I'm trying to use sinon right now.
I want to mock a constructor function named Dog
Dog = jest.fn(()=>{
return{
name:"spike",
bark:function(){
return "bhow " +this.name;
}
}
})
function foo(){
const d = new Dog();
return d.bark();
}
test("testing foo",()=>{
const result = foo();
expect(Dog).toHaveBeenCalledTimes(1);
expect(result).toBe("bhow spike");
expect(Dog.mock.instances.length).toBe(1);
expect(Dog.mock.instances[0].name).toBe("spike");
//this test failed with expected spike received undefined
});
but the expect(Dog.mock.instances[0].name).toBe("spike");
fails with expected spike received undefined
jest version 24.8.0
node version 10.15.0
When you call a function with the new operator, a new object is created and passed as the execution context (aka this) to the function. This object is then implicitly returned if the function does not return anything explicitly. You can have a look at the detailed explanation.
Also, take into account that an arrow function can never be used as a constructor.
From Jest documentation for mock functions:
mockFn.mock.instances
An array that contains all the object instances that have been instantiated from this mock function using new.
So, Jest mock functions are storing in the instances attribute the list of object instances that are being passed to the function (the newly created object that is passed as this to the function) every time you call it with the new operator.
But your constructor is not using the this object, so it remains empty. That is why when you check Dog.mock.instances[0].name you are getting undefined. If you change slightly your constructor to assign the name attribute to the this object you can see that your test passes:
Dog = jest.fn(function() {
this.name = "spike";
return{
name:"spike",
bark:function(){
return "bhow " +this.name;
}
}
})
Returning explicitly an object from a constructor function as you are doing is rarely used. The most usual way to define a constructor is to assign its properties to the this object. So, a solution to your problem would be to change your constructor function to:
Dog = jest.fn(function() {
this.name = "spike";
this.bark = function(){
return "bhow " +this.name;
}
})
Another solution, if you don't want to change the definition of your constructor function, would be to use the results attribute of the mock function in your test:
test("testing foo",()=>{
const result = foo();
expect(Dog).toHaveBeenCalledTimes(1);
expect(result).toBe("bhow spike");
expect(Dog.mock.instances.length).toBe(1);
expect(Dog.mock.results[0].value.name).toBe("spike");
});
I am new to nodejs. Using bluebird promises to get the response of an array of HTTP API calls, and storing derived results in an ElasticSearch.
Everything is working fine, except I am unable to access the variables within the 'then' function. Below is my code:
Promise.map(bucket_paths, function(path) {
this.path = path;
return getJson.getStoreJson(things,path.path);
}, {concurrency:1}).then(function(bucketStats){
bucketStats.map(function(bucketStat) {
var bucket_stats_json = {};
bucket_stats_json.timestamp = new Date();
bucket_stats_json.name = path.name ==> NOT WORKING
});
});
How can I access the path.name variable within the 'then' ? Error says 'path' is undefined.
The best way to do this is to package the data you need from one part of the promise chain into the resolved value that is sent onto the next part of the chain. In your case with Promise.map(), you're sending an array of data onto the .then() handler so the cleanest way to pass each path down to the next stage is to make it part of each array entry that Promise.map() is resolving. It appears you can just add it to the bucketStat data structure with an extra .then() as show below. When you get the data that corresponds to a path, you then add the path into that data structure so later on when you're walking through all the results, you have the .path property for each object.
You don't show any actual result here so I don't know what you're ultimately trying to end up with, but hopefully you can get the general idea from this.
Also, I switched to Promise.mapSeries() since that's a shortcut when you want concurrency set to 1.
Promise.mapSeries(bucket_paths, function(path) {
return getJson.getStoreJson(things,path.path).then(bucketStat => {
// add the path into this item's data so we can get to it later
bucketStat.path = path;
return bucketStat;
});
}).then(function(bucketStats){
return bucketStats.map(function(bucketStat) {
var bucket_stats_json = {};
bucket_stats_json.timestamp = new Date();
bucket_stats_json.name = bucketStat.path.name;
return bucket_status_json;
});
});
I might not be getting something but I am trying to test the callback content of a method but without calling the method.
The function I am trying to test
functionToSkip(param1, param2, function(arg1, arg2){
if(arg1){
// Do some things here
} else {
// Do other things here
}
}
What I am trying to do is to test the content of the callback function with differents args values that I can change in the tests and the parameter of the functionToSkip can be anything.
All I successfully did is to skip the call of the function but I cannot call the callback method.
I did stub the function to skip and even trying to give values to the callback method but there is not any logs showing.
var spy = sinon.stub(Class, "functionToSkip").calledWith(param1, param2, ("arg1","arg2"))
The main method that is calling the stubbed function works since I can see the logs prior of the function when I call it in the tests.
First of all, if functionToSkip is an instance method on Class, it will be a property on Class.prototype, not Class itself. In order to stub, you can do one of two things:
Create an instance, and create the stub:
instance = new Class(/*costructor arguments*/)
var stub = sinon.stub(instance, 'functionToSkip')
Or, stub on the prototype:
var stub = sinon.stub(Class.prototype, 'functionToSkip');
In the second case, since class prototypes are global state, I'd recommend restoring it-- preferably in something like mocha afterEach to ensure it gets cleaned up whether your test is successful or not. This way it doesn't screw with other tests in your run:
stub.restore()
Between the two, though, I recommend the first approach.
Next up... If you want to make assertions on the content of calls, the firs thing you'll probably want to do is assert that it was in fact called with the signature you're looking for:
sinon.assert.calledWith(stub, sinon.match.any, sinon.match.any, sinon.match.func)
The any matcher allows any value, and the func matcher requires a func. After that, you can obtain the callback function like so:
var cb = stub.firstCall.args[2]
And invoke it like so:
cb('arg1', 'arg2');
As to what assertions you'd do after invoking the callback function-- I'd have to know more about what you're trying to test about it to make recommendations.
I need to send requests between two separate .swfs, A and B. I have an interface, IRequest with the following methods:
public interface IRequest {
function get packagePath():String;
function get className():String;
function get functions():Vector.<String>;
function get parameters():Array;
function execute():void;
}
I implement it in a class, Request. One can create a new request as follows:
RequestManager.addToQueue(new Request("com.myPackage", "MyClass", "instance.method1.method2", "parameter"));
This creates a new Request with a supplied package, class-name, list of functions and parameters.
Things become complicated with a chain of function-calls and deciding if a function is actually a function or property (public function getMyThing():Object vs public function get myThing():Object).
For example, things are simple enough if the desired Request is new Request("com.myPackage", "MyClass", "getInstance", "");
Invoking that method is as simple as:
var theClass:Class = getDefinitionByName(packagePath + "." + className) as Class;
var theInstance:Object = theClass[functions[0]](); // Invokes com.myPackage.MyClass.getInstance()
However, this won't work if getInstance is a property/getter. Also, if there are numerous method calls, I'm not sure how to invoke the chain in one call. For example:
var theClass:Class = getDefinitionByName(packagePath + "." + className) as Class;
var object = theClass[functions[0]]()[functions[1]()[functions[2](); // Invokes com.myPackage.MyClass.firstMethod.secondMethod.thirdMethod()
However, I need to do this dynamically, and I don't see an easy way of dynamically chaining those [, ].
If anyone knows a nice way for me to be able to invoke methods from a String, that's essentially what I want to do.
"com.myPackage.MyClass.firstMethod.secondMethod.thirdMethod()", parameters
Thanks for the help,
I think doing a check whether that argument actually holds a function before invoking it would help.
var theClass:Class = getDefinitionByName(packagePath + "." + className) as Class;
if(theClass[functions[0]] is Function){
var theInstance:Object = theClass[functions[0]](); // Invokes com.myPackage.MyClass.getInstance()
}