javascriptreactjstestingaxiosmoxios

Specify response.request.responseURL in moxios


I'm currently trying to write some functionality that requires the response.request.responseURL value to be set when axios handles the response. However, I can't seem to set this value with moxios. Here's what my test looks like:

it('resets list selection if input contents were replaced', (done) => {
    component.currently_selected_list_value = 10;
    component.last_called_url = 'henkiehoutman';

    let input = domElt.querySelector('input');
    ReactTestUtils.Simulate.change(input);

    moxios.wait(() => {
        let request = moxios.requests.mostRecent();
        request.respondWith({
            status: 200,
            response: [{
                customer_info_customers: ['', '', '', '', ''],
                domain_info_customers: {},
            }],
            request: {responseURL: 'banaan'}
        }).then(() => {
            // The contents were replaced, so it's best to forget whatever our selection was.
            expect(component.currently_selected_list_value).toEqual(-1);
            done();
        });
    });
});

This is what my actual application looks like:

onChange (event) {
    return axios.get(
        this.props.ApiUrl + encodeURIComponent(event.target.value)
    ).then(
        (response) => {
            let response_url = response.request.responseURL;  // This is the value I want to set manually.
            if(this.shouldHandleResponse(response_url)){
                this.last_called_url = response_url;
                let data = response.data;
                this.setState({results: data, dropdown: data.length > 0});

                if ( this.currently_selected_list_value > max_index) {
                    this.currently_selected_list_value = max_index;
                }
            }
        }
    );
},

However, when I log what this value is, it just says undefined. And this is what the actual response.request value is (put it in a quote so it's a bit more readable):

LOG: Request{resolve: function (a) { ... }, reject: function (a) { ... }, config: Object{adapter: function mockAdapter(config) { ... }, transformRequest: Object{0: ...}, transformResponse: Object{0: ...}, timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, validateStatus: function validateStatus(status) { ... }, headers: Object{Accept: ..., X-CSRFToken: ...}, method: 'get', url: 'my_api_url/', data: undefined}, headers: Object{Accept: 'application/json, text/plain, /', X-CSRFToken: 'my_csrf_token'}, url: 'my_api_url/', timeout: 0, withCredentials: false, responseType: undefined}

This breaks my application, because a responseURL should always be defined. It looks like it's overwriting the request I defined in moxios. This is not necessarily a bad thing, because I assume it needs these things to function properly. However, it would be nice if I could add some values to this request.

So; How do I add a responseURL value to this request in moxios?


Solution

  • Turns out that it's not possible to set the responseURL because of the way I chained it to respondWith(). After checking this function in the moxios source code I saw that the values you pass in here really only have to do with actual data being returned, not an actual response object.

    I also saw that the respondWith() function returns a Promise object, which is quite logical. I figured that I should not set anything on the Promise, but on the actual request. So I assigned the returned Promise to a promise variable and unchained the .then() part of the test. I set the request'sresponseURL after that. Then I called promise.then() again to assert that my test has passed.

    Here is what I eventually went for:

    it('resets list selection if input contents were replaced', (done) => {
        component.currently_selected_list_value = 10;
        component.last_called_url = 'henkiehoutman';
    
        let input = domElt.querySelector('input');
        ReactTestUtils.Simulate.change(input);
    
        moxios.wait(() => {
            let request = moxios.requests.mostRecent();
            let promise = request.respondWith({
                status: 200,
                response: [{
                    customer_info_customers: ['', '', '', '', ''],
                    domain_info_customers: {},
                }],
            });
            request.responseURL = 'banaan';
    
            promise.then(() => {
                // The contents were replaced, so it's best to forget whatever our selection was.
                expect(component.currently_selected_list_value).toEqual(-1);
                done();
            });
        });
    });