view doesn't load when I mock backend

2019-04-14 10:25发布

问题:

I'm trying to test one particular element of user interface. To do so I need particular request to my backend to respond with predefined data, but all other requests should pass through. Here's how I do it (coffee for more readability):

describe 'select2 combobox widget', ()->
  httpBackendMock = () ->
     angular.module 'httpBackendMock', ['ngMockE2E', 'fmAppApp']
        .run ($httpBackend)->
            dummyCategories = [
               {id: 1, name: 'foo', icon: '', user_id: 5},
               {id: 2, name: 'bar', icon: '', user_id: 5},
               {id: 3, name: 'baz', icon: '', user_id: 5},
               {id: 4, name: 'quax', icon: '', user_id: 5}
            ]

            $httpBackend.whenGET '/api/categories'
                .respond ()->
                    [200, dummyCategories]
            $httpBackend.whenGET /.*/
                .passThrough()
            $httpBackend.whenGET /^\/views\//
                .passThrough()
            $httpBackend.whenGET /^\/scripts\/.*/
                .passThrough()
            $httpBackend.whenGET /^\/scripts\//
                .passThrough()
            $httpBackend.whenGET /^\/bower_components\//
                .passThrough()
            $httpBackend.whenGET(/\.html$/).passThrough()

  browser
     .addMockModule 'httpBackendMock', httpBackendMock

so basically what I do here is create new module on top of my application module fmAppApp and angular ngMockE2E and tell Protractor about it.

And for the sake of completeness I'll show here one simple statement inside this describe block:

it 'should allow user to type in anything', ()->
    browser.get 'http://localhost:9000/#/'
    element By.model 'category.selected'
        .click()
    input = element By.css '.ui-select-search'
    input.sendKeys 'newtestcategory'
    expect input.getAttribute('value')
        .toBe 'newtestcategory'

when I run grunt protractor it opens browser, navigates to specified url (http://localhost:9000/#/) as it should and then I see blank page and spec failures with this error: NoSuchElementError: No element found using locator: by.model("category.selected")

Unfortunately this message is all I have since I can't open firebug and see what went wrong for obvious reasons. I guess I could redirect logging from browser console somehow and see what is root of evil here but I don't know how. Maybe someone encountered that as well and knows what it might be? Update: I did as Cétia below suggested and I got this message in logs:

message: 'http://localhost:9000/bower_components/angular/angular.js 11607:24 Error: Unexpected request: POST /api/login

Now why is that? Should I add 'api/login' to passThrough() ?

回答1:

To be sure that your mock is loaded, you can add console.log inside, and, in your protractor test add :

browser.manage().logs().get('browser').then(function(browserLog) {
    console.log('log: ' + require('util').inspect(browserLog));
});

In order to output browser logs in your protractor console (after your browser.get).



回答2:

It seems I didn't provide sufficient information. I left out some code that I thought was irrelevant with intent to not overwhelm you, but as it turned out it was a stumbling block.

browser.get 'http://localhost:9000/#/'
element By.model 'email'
  .sendKeys 'dima@mail'
element By.model 'password'
  .sendKeys '123456'
element By.cssContainingText 'form[name=login] button', 'Войти'
  .click()

This code is responsible for logging user in, I need it here because unauthorized users aren't allowed to see the view I wanted to test. I thought I made sure all requests make it through, but of course I forgot that my login request is a POST request. So problem was solved simply by adding

$httpBackend.whenPOST /.*/
      .passThrough()