Skip to content

How to mock Http requests in Protractor tests #412

Closed

Description

@daddywoodland

Hi,

I'd like to mock the response from an API in my end to end tests but I'm not sure how to include and use MockBackend in the project.

Can you offer any advice?

Cheers,

Activity

  1. alvipeo commented on Mar 11, 2016

    @alvipeo

    This is how I do it in my tests:

    beforeEachProviders(() => [
            HTTP_PROVIDERS,
            provide(XHRBackend, { useClass: MockBackend })
        ]);
    
    it("should return items", inject([XHRBackend], fakeAsync((mockBackend) => {
    
                const firstItem = {
                    "ItemType": 0,
                    "ImageUri": "~/test/_DSC4464_DxO.jpg",
                    "ModifiedDate": null, "Name": "_DSC4464_DxO.jpg",
                    "OrderIdx": 1, "Path": "~/test/_DSC4464_DxO.jpg",
                    "ThumbUri": "http://localhost:49413/Content/images/uploads/test/_thumbs/_DSC4464_DxO_200_200_133_200.jpg"
                };
                const secondItem = {
                    "ItemType": 0,
                    "ImageUri": "~/test/_DSC4469_DxO.jpg",
                    "ModifiedDate": null, "Name": "_DSC4469_DxO.jpg",
                    "OrderIdx": 2, "Path": "~/test/_DSC4469_DxO.jpg",
                    "ThumbUri": "http://localhost:49413/Content/images/uploads/test/_thumbs/_DSC4469_DxO_200_200_200_133.jpg"
                };
                // first we register a mock response - when a connection 
                // comes in, we will respond by giving it an array of (one)
                // blog entries
                mockBackend.connections.subscribe(
                    (connection: MockConnection) => {
                        connection.mockRespond(new Response(
                            new ResponseOptions({
                                body: [
                                    firstItem,
                                    secondItem
                                ]
                            }
                            )));
                    });
    
                let called = false;
                // with our mock response configured, we now can 
                // ask the blog service to get our blog entries
                // and then test them
                dirItemsSrv.getItems$("~/").subscribe((dirItems: Array<DirItem>) => {
                    expect(dirItems.length).toBe(2);
    ...
                    called = true;
                });
                expect(called).toBe(true);
            })));
    
  2. daddywoodland commented on Mar 11, 2016

    @daddywoodland
    Author

    Thanks @alvipeo I'm trying it now, just struggling to get my dataService (your dirItemSrv) into the test. I'll keep trying and let you know how I get on.

  3. samvloeberghs commented on Mar 11, 2016

    @samvloeberghs
    Contributor

    hi @daddywoodland @alvipeo
    Just to make some things clear ( perhaps also for other visitors in the future ), you are not doing E2E tests. You're unit testing a service where you are mocking out your dependencies ( in this case the XHRBackend service )

  4. daddywoodland commented on Mar 11, 2016

    @daddywoodland
    Author

    Hi @samvloeberghs,

    The terminology does trigger some interesting conversations.

    As you say it's a unit test but not of a service, I'm testing a unit of behaviour within my UI (port level testing).

    Protractor is my mechanism for accessing the closed system to test a behaviour, and since Protractor is always labelled as an end to end testing tool, I mistakenly used the term.

    Either way, I'm after a Protractor, not Karma solution to this problem :o)

    Cheers,

  5. changed the title [-]How to mock Http requests in end to end tests[/-] [+]How to mock Http requests in Protractor tests[/+] on Mar 11, 2016
  6. alvipeo commented on Mar 11, 2016

    @alvipeo

    I actually do integration tests, not unit tests (well, rarely I do them too). That's the way that works best for me. So Karma is in my case.

  7. daddywoodland commented on Mar 16, 2016

    @daddywoodland
    Author

    I've been looking at this on and off for the last few days without making much progress. I think the technique suggested above (and everywhere else on t'internet) involves configuring the injection before the component/service is initialised. However as protractor is running tests against an app that's already running it's not working.

    I'm going to look at initialising the application with the mock backend in place so that I can configure mocked responses on a test by test basis.

  8. samvloeberghs commented on Mar 16, 2016

    @samvloeberghs
    Contributor

    In the past I've done this by mocking my backend with a node-red implementation. By setting a flag that was then triggering the initialisation of this mocked API and redirecting/proxying the API address to that mocked API.

    But that said: When doing E2E tests you should keep the mocking to the minimum, trying to avoid it completely. E2E testing explicitly means that you test end to end, real app till real backend.

    If you don't want to polute your production DB for example, you should have a staging or dev server running next to your UAT or prod environment, where you test against regressions. Perhaps use docker to instantiate a setup on the fly, ..

  9. samvloeberghs commented on Mar 16, 2016

    @samvloeberghs
    Contributor

    To elaborate on your last comment: It's indeed hard and probably unneeded to change the app implementation on runtime. What you could do is change the environment. While running your protractor config, proxy the requests and point them to the mocked API

    -> run protractor, set flag
    -> if flag set, setup proxy
    -> call to http://real.api.com, going trough proxy, proxy it to http://mocked.api.com
    -> protractor done, unset flag
    -> destroy proxy

    Just some quick thoughts :)

  10. daddywoodland commented on Mar 16, 2016

    @daddywoodland
    Author

    Thanks @samvloeberghs I'll take that into account when trying out mocking the HTTP response. I was looking at json-server as a possible solution for mocking the API.

    Regarding the reference to 'E2E', these aren't end to end tests but unit tests of the behaviour of the front end as a closed component. I've seen it called 'port level testing', 'sociable unit tests' and 'behavioural unit testing'.

    Ultimately I need to mock any requests that move across the boundary of my component, in this case calls the the API.

    If you're unfamiliar and are interested in the idea, the approach was triggered from a talk by Ian Cooper I saw a couple of years ago. I didn't see this one at NDC 2013 but it's the same presentation I believe.

    Cheers!

  11. PatrickJS commented on Sep 2, 2017

    @PatrickJS
    Owner

    sorry this may sound super rule but I'm closing long standing issues and refactoring the codebase. If you run into this problem again feel free to open another issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions