Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to mock Http requests in Protractor tests #412

Closed
daddywoodland opened this issue Mar 11, 2016 · 10 comments
Closed

How to mock Http requests in Protractor tests #412

daddywoodland opened this issue Mar 11, 2016 · 10 comments

Comments

@daddywoodland
Copy link

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,

@alvipeo
Copy link

alvipeo commented Mar 11, 2016

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);
        })));

@daddywoodland
Copy link
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.

@samvloeberghs
Copy link
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 )

@daddywoodland
Copy link
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,

@daddywoodland daddywoodland changed the title How to mock Http requests in end to end tests How to mock Http requests in Protractor tests Mar 11, 2016
@alvipeo
Copy link

alvipeo commented Mar 11, 2016

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.

@daddywoodland
Copy link
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.

@samvloeberghs
Copy link
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, ..

@samvloeberghs
Copy link
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 :)

@daddywoodland
Copy link
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!

@PatrickJS
Copy link
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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants