Mocking async service which makes a callback

611 views
Skip to first unread message

rost...@gmail.com

unread,
Feb 20, 2020, 7:38:45 AM2/20/20
to mountebank-discuss
We have an async service that is kicked off via an initiate endpoint, this itself is easy to mock, as it just returns a 202 pending status. Is it possible to have mountebank wait say 10 secs then make a request out back to the calling api to a callback endpoint, posting the result of the async job? I see it’s possible to use npm modules, so would it be possible to use the request npm library inside an injection to post a stubbed result to the callback endpoint in the api which is itself calling mountebank?

Brandon Byars

unread,
Feb 20, 2020, 9:54:50 AM2/20/20
to rost...@gmail.com, mountebank-discuss
Yeah it's possible but ugly at the moment; this is definitely an opportunity to improve the product to make it easier. For example, you could use a shellTransform to shell out to a separate app that sleeps 10 seconds and calls the callback endpoint without really transforming the response, which is passed back by mountebank's core engine.

I'll add a feature request to make async callbacks easier in the future, will have to think about how to do it.
-Brandon


On Thu, Feb 20, 2020 at 6:38 AM <rost...@gmail.com> wrote:
We have an async service that is kicked off via an initiate endpoint, this itself is easy to mock, as it just returns a 202 pending status. Is it possible to have mountebank wait say 10 secs then make a request out back to the calling api to a callback endpoint, posting the result of the async job? I see it’s possible to use npm modules, so would it be possible to use the request npm library inside an injection to post a stubbed result to the callback endpoint in the api which is itself calling mountebank?

--
You received this message because you are subscribed to the Google Groups "mountebank-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mountebank-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mountebank-discuss/cd51de28-f2f8-4f4d-b3b0-ef72469eb51a%40googlegroups.com.

rost...@gmail.com

unread,
Feb 22, 2020, 11:02:37 PM2/22/20
to mountebank-discuss
Thanks for the reply. So as a short term solution making requests in a timeout from within an injection would work? When I have more free time I’d be keen to experiment with getting the shell transform approach working and help document the process.

Brandon Byars

unread,
Feb 24, 2020, 8:37:28 PM2/24/20
to rost...@gmail.com, mountebank-discuss
I’m not sure if the injection approach would work, but i suspect not. I think the problem is that even an asynchronous injection would have to return the response before making the callback, at which point the function variable would be garbage collected as there would no longer be a reference to it. I believe, but have not proved, that the shellTransform approach is the o pay way currently to maintain context long enough to send the callback. 

On Sat, Feb 22, 2020 at 10:02 PM <rost...@gmail.com> wrote:
Thanks for the reply. So as a short term solution making requests in a timeout from within an injection would work? When I have more free time I’d be keen to experiment with getting the shell transform approach working and help document the process.

--
You received this message because you are subscribed to the Google Groups "mountebank-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mountebank-disc...@googlegroups.com.
--
Sent from Gmail Mobile

rost...@gmail.com

unread,
Feb 25, 2020, 11:33:36 AM2/25/20
to mountebank-discuss
You're right, I had trouble trying to do it in an injection. I'm proceeding down the shell transform method for now, so far so good seems to be working, just need to plumb in a few more scenarios and test it out. Thanks for your Help!


On Monday, February 24, 2020 at 8:37:28 PM UTC-5, Brandon Byars wrote:
I’m not sure if the injection approach would work, but i suspect not. I think the problem is that even an asynchronous injection would have to return the response before making the callback, at which point the function variable would be garbage collected as there would no longer be a reference to it. I believe, but have not proved, that the shellTransform approach is the o pay way currently to maintain context long enough to send the callback. 
On Sat, Feb 22, 2020 at 10:02 PM <rost...@gmail.com> wrote:
Thanks for the reply. So as a short term solution making requests in a timeout from within an injection would work? When I have more free time I’d be keen to experiment with getting the shell transform approach working and help document the process.

--
You received this message because you are subscribed to the Google Groups "mountebank-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mountebank-discuss+unsub...@googlegroups.com.

sassan.s...@gmail.com

unread,
May 20, 2020, 7:42:14 PM5/20/20
to mountebank-discuss
Hey guys. I came across this post when I was trying to build an async service myself. I have good news! It IS possible to do it with a JS injection. You need to use an async helper function which is required into your injected function. The following approach worked for me:

// you can put this in a separate file like callback-helper.js
async function callbackExecute(callBackRequest){
     await sleep(callBackRequest.wait);

     fetch(callBackRequest.URL, {
     method: callBackRequest.method,
     headers: callBackRequest.headers,
     body: callBackRequest.body
     });
}

// this is the function you inject into your imposter
function asyncInjection(config){
     const callbackHelper = require("blah blah/callback-helper")
     const callBackRequest = 
     { 
       method: "POST",
       body: "blah blah",
       URL: "blah",
       wait: 5000
     }

     callbackHelper.callbackExecute(callBackRequest);

     var stubResponse = blah blah
     config.callback(stubResponse);
}

I did not copy this from my code so there might be typos. Plus let me know if any of the "blah"s don't make sense.
With this approach, your async service will immediately return a response while the callbackExecute is running asynchronously and will send the callback request after 5000 ms. 
This is a much much lighter way compared to shell transform which might eat up all your CPU during a load test. Cheers.

On Tuesday, February 25, 2020 at 12:37:28 PM UTC+11, Brandon Byars wrote:
I’m not sure if the injection approach would work, but i suspect not. I think the problem is that even an asynchronous injection would have to return the response before making the callback, at which point the function variable would be garbage collected as there would no longer be a reference to it. I believe, but have not proved, that the shellTransform approach is the o pay way currently to maintain context long enough to send the callback. 
On Sat, Feb 22, 2020 at 10:02 PM <rost...@gmail.com> wrote:
Thanks for the reply. So as a short term solution making requests in a timeout from within an injection would work? When I have more free time I’d be keen to experiment with getting the shell transform approach working and help document the process.

--
You received this message because you are subscribed to the Google Groups "mountebank-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mountebank-discuss+unsub...@googlegroups.com.

Brandon Byars

unread,
May 21, 2020, 10:23:58 AM5/21/20
to sassan.s...@gmail.com, mountebank-discuss
Nice! Thanks for sharing.
-Brandon

To unsubscribe from this group and stop receiving emails from it, send an email to mountebank-disc...@googlegroups.com.
--
Sent from Gmail Mobile

--
You received this message because you are subscribed to the Google Groups "mountebank-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mountebank-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mountebank-discuss/ba4b7397-c205-4f7a-a648-79ad852764a2%40googlegroups.com.

Juan Luis Garcia

unread,
Sep 29, 2020, 1:57:43 PM9/29/20
to mountebank-discuss
I tried this approach and sadly, if there are any dependencies in any "external" class, is not found; even if installed globally per the documentation.
For instance, I needed "aws-sdk" to perform some calls to a SQS queue.  I added the dependency to the " callback-helper.js" class; and that would not work.
But, moving the same dependency to the calling function, would be just fine, as long as "aws-sdk" is installed globally.
So, I had to put everything in one file, which prevented me from implementing a synchronous implementation, but still worked for what I intended to do.

Justin Backman

unread,
Jun 7, 2021, 2:50:35 PM6/7/21
to mountebank-discuss
Did anyone get it working with the external class?

Deepak Bharti

unread,
Jul 2, 2021, 6:04:38 AM7/2/21
to mountebank-discuss
Hi all,
I'm imporitng a JS file in injection. But while giving relative path it is not working. Only with full path it is working.
{
      "predicates":[
        {
          "equals":{
            "path":"/allUser"
          }
        }
      ],
      "responses":[
        {
          "inject":"function(config){const user=require('C:/Users/deepak.bharti01/Desktop/database/scripts/test.js'); user.getAll().then(res=>{config.callback({body:res})})} "
        }
      ]
    }

Folder structure :
scripts==>
                  ||test.js
src==>
                  ||services===> stubs===>getRequest.json
Reply all
Reply to author
Forward
0 new messages