Mock response body not populating from pre-request set environment variables

I have a mocked collection of requests whose example responses are dependent on the previous response’s returned data. Requests are always made sequentially in this order:

  1. /channels (Populates initial channel data)
    Sets the allChannels environment variable in the test scripts which is simply an array of objects.

  2. /channels/:id
    Sets a selectedChannelId from the pm.request.url.path[1] and a selectedChannel from looking up the channel by id in the allChannels list in the pre-request script.

  3. /:channel_id/threads ( Creates a random creator user id and username for each thread )
    Sets a currentUsers object environment variable in test scripts where user ids are keys and usernames are the properties.
    {"creator_id": 901,"creator_username": "Rodrick.Mayer34"}

  4. /users/:id
    Sets a selectedUser from the pm.request.url.path[1] and a selectedUsername from looking up the channel by id in the currentUsers list in the pre-request script.

*Note: This implementation exclusively using environment variables.


Above, we can see that all environment variables are in-fact being properly set in each of the corresponding pre-request scripts.

*Note: All response/request headers have been set to content-type: application/json as mentioned in previous threads as a potential issue

The Problem - bug?

Both /users/:id and /channels/:id are not properly populating the example reponse body from the {{selectedUsername}} and {{selectedChannel}} environment variables set in pre-request scripts.

User by id response / environment & Mock example response

Channel by id response / environment & Mock example response

What I’ve tried

  • Every configuration I can think of for content-type
  • Using globals / using variables
  • Every possible syntax variation I could think of for dynamically populating the example response body
  • Logging the environment variables in the pre-request scripts works as expected
  • Tried pm.environment.unset after the requests have been made in the test scripts to see if resetting things makes a difference
  • Read all of the available docs and blog posts
  • Scoured this forum and stackoverflow

Note

Thank you for any help and suggestions… I’m really at a loss on this one. Here is the collection again: https://www.getpostman.com/collections/a4764f8b5c205057d251

*Remember: Requests are intended to be made in the above order. In order to replicate this issue you’d have to copy correct ids etc from previous responses for the next response.

Hello @kbrinso, welcome to the community! :wave:

As I can see from the attached collection, you’re updating the environment using the pre-request script and expecting the mock to use that updated environment value.

Are you using the collection runner/monitor to make these requests?

Hi @singhsivcan, thanks for the quick response and welcome to the community!

I’m not using the collection runner to sequentially run the requests. I’m doing so manually to verify they were at least presenting the expected behavior before writing tests. Do you think it’s worth setting up tests and automating running each of the requests in the collection runner? It does seem that all my data is being properly set in the environment. At the same time, I don’t quite understand why/how it’s possible for the collection runner to return something different than manually running the requests sequentially. Anyways, I’ll try just about anything at this point. I’ll test this out now and share if I find anything different from running these in the collection runner.

Oh, I was just asking because actually the collection runner runs the collection in a sandboxed environment, and only after the collection runner has finished the run will it update the environment on sync.
So, that’s why I was asking, because that would break the case.

However, since you’re running it manually this should’ve ideally worked.

Now,
On going through your pre-request script, I am unable to understand what exactly you’re doing.

  1. In your 1st request, channels/:id,
// Why this? You've just set the selectedChannelId - with that value
const chanData = pm.environment.get(pm.request.url.path[1].toString());

// Did you mean
const chanId = pm.environment.get("selectedChannelId");
pm.environment.set("selectedChannelData", chanId);

What exactly is going on here?
We just read the value from the environment that is of the selectedChannelId and then we’ve set the same value as the selectedChannelData.

I am guessing, you need to dig into your scripts, there seems to be some confusion here.

Also,
If you’re updating the environment from a pre-request script and then expecting the mock to use that updated value while the request is ran, it wouldn’t happen.

Why?
Because as soon as you send a request, the request is ran in a sandboxed environment, and the variables that are updated are actually updated after the whole request execution has finished and after the tests scripts have also finished running, is when the change in the environment is actually synced to the server and that’s when the mock will be using the updated environment.

If you want to update the environment on the fly through the pre-request script then you need to use the Postman API in the pre-request script along with the help of pm.sendRequest

I was unable to debug it further given the lack of data on my end.

1 Like

Ah, thank you so much! This is just the clarification I was looking for. I was really hoping that this flow could work within the Postman app, but it seems that I’d have to use the API in order for this to work.