Mocking out AJAX calls with Dojo XHR - dojo

I'm attempting to mock the response of a dojo xhr request, but I haven't found a good solution.
Ideally, I'd like to see a solution similar to the jQuery mockjax plugin where I can set a specific call based on a url, e.g.:
$.mockjax({
url: '/restful/fortune',
responseTime: 750,
responseText: {
status: 'success',
fortune: 'Are you a turtle?'
}
});
My initial thought was to utilize the "/dojo/io/send" channel, but I haven't been able to get a modified response to be loaded after modifying the dojo Deferred object.
The other thought is to use a pass-through method that would determine if an actual xhr request should be made, e.g.:
function xhrRequest(xhrArgs) {
if(shouldMock) {
var fakeReturnJson = dojo.toJson({
howdy: "that's odd!",
isStrange: false
});
return fakeReturnJson;
} else {
dojo.xhr(xhrArgs);
}
}
Can someone tell me the best way to go about mocking dojo xhr calls?
Thanks!

It's an old question, but I think you should do your mocking using Sinon.js
However you will need to put the following:
has: { native-xhr2: false }
into your dojoConfig for it to work in 1.8

I haven't heard of any Dojo specific libraries similar to Mockjax. But what I think you could try is use Mockjax with Dojo. This should be pretty easy to do since all you'll have to do is use JQuery during development only for testing with Mockjax and then remove it once development is complete.

I use your second suggestion. Currently, I have a transport layer (simple js class) and 2 implementations (XhrTransport and MockTransport). I then switch in which I need without changing the widget code.
Widgets call the server with:
Controller.send(aServerCall);
where aServerCall is a simple value object with the server endpoint, params and callback.
This way, you can add nice things to the controller that will apply to all server calls (such as logging, analytics, generic error handling...) and also mock out the entire server when doing unit tests.
For the MockTransport, I simply return canned json data from static .js files in the format that the widget expects.

Related

API call inside a JavaScript function present in a feature file

I tried my best but could not find information on calling an API inside the Javascript function when dealing with automation in Karate. Now, I might get suggestions to call the API outside the function and then do operations inside the function. However, my use case is such that I have to call the API inside the function only. Is there a way to do this?
One approach is to create a Java file and then write the code in java. However, I specifically want to know if there is any way to call an API inside a JS function in a FEATURE FILE itself.
First, these kinds of "clever" tests are not recommended, please read this to understand why: https://stackoverflow.com/a/54126724/143475
If you still want to do this, read on.
First - most of the time, this kind of need can be achieved by doing a call to a second feature file:
* if (condition) karate.call('first.feature')
Finally, this is an experimental and un-documented feature in Karate, but there is a JS API to perform HTTP requests:
* eval
"""
var http = karate.http('https://httpbin.org');
http.path('anything');
var response = http.get().body;
karate.log('response:', response);
"""
It is a "fluent API" so you can do everything in one-line:
var body = karate.http('https://httpbin.org/get').get().body;
If you need details, read the source-code of the HttpRequestBuilder and Response classes in the Karate project.

Create mocks in api functional testing with Symfony

I'm dealing with a problem I have in a Symfony 4 API functional tests. My functional tests consists in making requests to the API and analyze the response given. I've been working like this and works fine.
The problem comes with a new API method I'm implementing which needs the perform a request to an external service. I want to mock during my tests, but I don't know how can I create a mock that persists when the API receives the request from the functional test.
I've been thinking about something like create mocks which are always used in the test environment but I haven't found anything...
you can check in http-client service called url and if it compare your external api url return certain response, it will be look something like this:
$guzzleServiceMock = $this
->getMockBuilder(GuzzleHttp\Client::class)->disableOriginalConstructor()
->setMethods(['get'])
->getMock();
$guzzleServiceMock
->expects($this->any())
->method('get')
->with(
$this->stringContains('/external/api/route')
)
->willReturnCallback(
function ($uri, $options = []) {
return new Response(
200,
[],
'{"result": {
"status": "success",
"data": "fake data",
}}'
);
}
);
next step you will need to inject service into container, with this question you can look this repo, there are good examples of how this can be done: https://github.com/peakle/symfony-4-service-mock-examples/blob/master/tests/Util/BaseServiceTest.php
I'm not sure if I understand correctly, but if you'd like to mock an external API (meaning your application is connecting to another application on another server), one solution would be to actually lunch a mock server to replace your actual external server.
Either you implement such a mock server yourself or you use an existing solution such as http://wiremock.org/

Passing javascript variable to velocity variable templete

I have installed xwiki successfully and able to generate wiki pages using velocity template language.
Could anyone please tell me that how can I pass javascript varible to velocity templete. I have gone through few forums that I need to pass the parameter to server to get this but I have no idea. Please find the files below.
<script type="text/javascript">
function generateFunction()
{
var variable = document.getElementById('text').value;
}
</script>
#set($test = "variable")
$test
You have to make an ajax call from the client to the server.If you're using jquery, you would have something like:
$.post('/send/my/var', { 'variable' : value });
Without jquery, see this XmlHttpRequest documentation.
And then, on the server side, the /send/my/var URL should reach a template where you can do:
#set($test = $params.variable)
And you would do something useful with it on the server-side, like store it in the session, in the database, etc.
If you need to send back something from Velocity to Javascript, then you'll typically have to format JSON code, and add an asynchronous completion callback parameter to the ajax call:
$.post('/send/my/var', { 'variable' : value },
function(data)
{
// do something with data sent back from the server
});
It's also possible to have synchronous calls, that is to have javascript wait for the server response, but it's generally a bad idea to do so and I won't extrapolate on it here.
As a final note, you should also implement a proper error handling. With jQuery for instance, the syntax would be:
$(document).ajaxError(function(event, jqxhr, settings, message)
{
console.log(message);
});
It can't be done,
Apache Velocity template is a server side engine,
Meaning that on the server, Velocity will get the template and try to render, only after it finished to render the template, it will be returned to client which will execute client code as Javascript
Velocity alternative is freemarker, which I found similar question and answer , Question:
How to call freemarker function with param from javascript
Answer:
There's no way for the client side web browser code to call a server side Freemarker function

intern test not using configured registry requestProvider in dojo

I'm following this article to mock response in dojo.
My mocker is very similar to the one in the article except this:
registry.register(/\/testIntern/, function (url, options) {
return when({
value: "Hello World"
});
In my understanding, this should map to any request that contains "/testIntern" on the address.
My testcase is quite simple:
// similar to example
var testRest= new Rest("/testIntern", true);
testRest("").then(lang.hitch(this, function (data) {
assert.deepEqual("Hello World", data.value, "Expected 'Hello World', but got" + data.value);
}));
It really should be quite simple. But when I run this test, I got 404 Not Found. It looks like the REST call in the test doesn't try to use the mocking service. Why?
You are generally correct in your thought that registering a URL with dojo/request/registry should pass anything referencing that URL via dojo/request through your handler.
Unfortunately, dojo/store/JsonRest uses the dojo/_base/xhr module which uses dojo/request/xhr directly, not dojo/request. Any registrations created with dojo/request/registry (and any setting of defaultProvider) will unfortunately be lost on JsonRest.
You might want to have a look at dstore - its Rest store implements the same server requests as dojo/store/JsonRest but it uses dojo/request instead of being hard-coded to a specific provider. (dojo/request defaults to dojo/request/xhr in browsers anyway, but can be overridden via dojoConfig.requestProvider.) dstore contains adapters for translating between dstore's API and the dojo/store API, if you need to use it with widgets that operate with the latter.

dojo.xhrGet or dojo.xhrPost

I'm very new at this, in fact this is my first Dojo attempt. I'm trying to get data from a website with:
<script
text="text/javascript"
src="http://o.aolcdn.com/dojo/1.3/dojo/dojo.xd.js"
djConfig="parseOnLoad:true,isDebug:true"
></script>
<script type="text/javascript">
//How are we supposed to know what else to include in the dojo thing? like query?
dojo.addOnLoad(function(){
console.log("hi");
dojo.xhrPost({
url: "http://www.scrapbookingsuppliesrus.com/catalog/layout", //who knows how to set relative urls?
handleAs: "json", //get json data from server
load: function(response, ioArgs){
console.log("got");
console.log(response); //helps with the debugging
return response; //that way goods should be a very large array of the data we want
},
error: function(response, ioArgs){
console.log("nope didn't make it", response+' '+ioArgs); //helps with the debugging
return response; //who knows what this does
} //last item, thus no extra comma
});
});
</script>
But nothing happens. While I'm at it, what exactly is the response and ioArgs variables. They're supposed to magically be the response to the request that I guess is specially defined already. But, who knows. Further, I figured after every attempt it would trigger something in load or error, but alas.
There used to be an error that I was going to a prohibited uri, but then firebug would reference a very large dojo script where it was impossible to tell why it was broken. What environment are the rest of you developing on?
Well, there are a couple of issues.
Lets start with the very easy ones first.
When you are developing you want to use the "uncompressed" version of Dojo, which can be found by appending .uncompressed.js to the path of the Dojo library being used:
http://o.aolcdn.com/dojo/1.3/dojo/dojo.xd.js.uncompressed.js
This will make it much easier to see what breaks, if it is in core-Dojo that is.
Next, the djConfig parameter. I'm quite certain that Dojo can handle a string, but traditionally it has been defined with an object, so, once you've included your Dojo library:
<script src="path to dojo"></script>
Start a new script block and define the djConfig object in there:
<script>
djConfig = {
parseOnLoad: true,
isDebug: true
};
</script>
Next simplest, I use IntelliJ JIDEA to develop, it has build-in code-sense for Dojo, makes life much easier. Otherwise, the standard package, Firefox + Firebug.
The complex stuff:
It seems that you are requesting data using the XHR method, hopefully you are aware that this means that your script and the data being accessed must reside on the same domain, if they don't you'll have security errors. How can this be solved? you use the technique called cross-domain scripting, which dojo also supports via the dojo.io.script.get functionality.
The more complex stuff:
Dojo works with something called "Deferred" objects. That means that the request doesn't actually go out as soon as the object is created, rather it goes out when you ask it to go out, that's the concept of "Deferred", you defer the execution of a block of code to a later time. The way this problem would then be solvedin your case is like this:
var deferred = dojo.xhrPost({
url: "http://www.scrapbookingsuppliesrus.com/catalog/layout", //who knows how to set relative urls?
handleAs: "json" //get json data from server
});
if(deferred) {
deferred.addCallback(function(response){
console.log("got");
console.log(response); //helps with the debugging
return response; //that way goods should be a very large array of the data we want
});
deferred.addErrback(function(response){
console.log("nope didn't make it", response+' '+ioArgs); //helps with the debugging
return response; //who knows what this does
});
}
And this should work out now.
As a personal note, i would not recommend using XHR but rather the dojo.io.script.get methodology, which over the long term is much more portable.
There where several very basic errors in your code.
<script ... djConfig="parseOnLoad:true,isDebug:true"/></script>
Here you use the short form of the script tag /> (which is forbidden) and at the same include the closing </script> too.
console.log("hi")
There is a semi-colon missing at the end of the statement
You try to load data from http://www.scrapbookingsuppliesrus.com/catalog/layout is your script also running on that domain? Else the security restrictions on Crossdomain-Ajax (google it) will prevent you from loading the data.
This question was also asked on the dojo-interest list and there are a few replies to the question on that list.
If your page is being served from www.scrapbookingsuppliesrus.com, then the code you've posted looks correct. The way you declare djConfig will work, and specifying load and error in the argument to xhrGet is correct. You're going to have dig in and debug.
Take a look in Firebug's Console window. You should see the GET request, complete with request and response HTTP headers, and the response text. If you don't see it, then I suspect something else has gone wrong before your onLoad function from being called - I'd throw a console.log at the top of that too. If your onLoad function isn't getting called, you may want to click the little down arrow in the Script tab and set "Break on all errors"
As to what the response and ioArgs are.
Response is, well, the response. If the request was successful, it will be the JSON object (or XML DOM object, or HTML DOM object, or text, depending on handleAs). If the request failed, it will contain an object with details about the error.
ioArgs is an object that includes a slew of lower-level details about the xhr request. As an asice, I've found that if you attach a callback to the deferred returned by xhrGet:
var dfd = dojo.xhrGet(args);
dfd.addCallbacks(function(response) {...}, function(error){...});
then the callback is not passed the ioArgs argument, just the response (or error).
dojocampus.org is the official dojo documentation site, and includes a lot of detail and examples.
Dojo: The Definitive Guide from O'Reilly is an excellent book. If you're going to be doing a lot of dojo dev., it's a great resource.
First, let's start with the basics, then you can add all the functionality.
You only need this to implement Ajax (take advantage of Dojo):
function sendData(dataToPost) {
dojo.xhrPost({
url: "http://myUrl.html",
postData: "data="+dataToPost,
handleAs: "text",
load: function(text){
getData(text);
},
error: function(error){
alert(error);
}
});
}
Now you can use the data in your "getData" function
function getData(text){
myVariable = text;
}
You can find many tutorials to see how it's implemented. This is the most complete example that I found, here you can see how it's implemented and all the code is available:
http://www.ibm.com/developerworks/java/library/j-hangman-app/index.html