Ember.js: TypeError não capturado: não é possível ler a propriedade 'hasRoute' de indefinido

Criado em 11 ago. 2015  ·  4Comentários  ·  Fonte: emberjs/ember.js

Tenho um serviço de autenticação para o qual estou tentando escrever um teste de unidade.

Quando não há uma transição anterior armazenada no serviço Auth, ele redireciona para uma rota específica.

O aplicativo funciona conforme o esperado, no entanto, os testes para este serviço fornecem o seguinte erro:

Uncaught TypeError: Cannot read property 'hasRoute' of undefined

Não sei como depurar / resolver isso. O que está acontecendo?

Este é meu serviço de autenticação:

import Ember from 'ember';
import config from '../config/environment';

export default Ember.Service.extend({
    routing: Ember.inject.service('-routing'),
    loginCapable: true,
    localStorageKey: config.localStorageKeys.user,

    checkAuth(priorTransition){
        this.set('priorTransition', priorTransition);
        return this.get('isLoggedIn');
    },

    isLoggedIn: Ember.computed('user', function(){
        return !!this.get('user');
    }),

    init(){
        this.set('user', JSON.parse(window.localStorage.getItem( this.get("localStorageKey") )) );
    },

    login(adID){
        return Ember.$.ajax(
            config.apiHost + config.apiVersion + "/getLdapInfo",{
                type: 'GET',
                data: "adID="+adID
            }).then(json => {
                this.set('user', json);

                window.localStorage.setItem( this.get("localStorageKey") , JSON.stringify(json));

                var priorTransition = this.get('priorTransition');
                if( priorTransition )
                {
                    priorTransition.retry();
                    this.set('priorTransition', null);
                }else{
                    this.get('routing').transitionTo('index');

                }
            }, xhr => {
                return xhr.responseJSON ? xhr.responseJSON.message : "Login failed";
            });
    }
});

E meu roteador:

import Ember from 'ember';
import config from './config/environment';

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {
  this.route('authenticated', { path: '/' }, function(){
    this.route('index', { resetNamespace: true });
  });
  this.route('login');
});

export default Router;

Aqui está o teste para esse serviço:

import { moduleFor, test } from 'ember-qunit';
import Ember from 'ember';
import startApp from 'recruiter-admin/tests/helpers/start-app';
import Pretender from 'pretender';

var server,
    application;

var user = [{
            "adID":"uniqueID",
            "first_name":"First Name",
            "last_name":"Last Name",
            "employee_type":"Regular",
            "employee_id":"12345",
            "manager":"CN=managerID,OU=Employees,OU=company Users,DC=company,DC=com",
            "success":true
            }];

function jsonResponse(json, status = 200) {
    return [status, {"Content-Type": "application/json"}, JSON.stringify(json)];
}

moduleFor('service:auth', 'Unit | Service | auth', {
    unit:true,
    needs:['router:main'],
    beforeEach(){
        application = startApp();

        server = new Pretender(function(){
            this.get('/getLdapInfo', function(req){
                return jsonResponse(user.findBy('adID',req.queryParams.adID));
            });
        });
    },

    afterEach(){
        Ember.run(application, 'destroy');
        if( server ){
            server.shutdown();
        }
    }
});

// Replace this with your real tests.
test('it exists', function(assert) {
    var service = this.subject();
    assert.ok(service);
});

test('isLoggedIn Testing', function(assert){
    var service = this.subject();
    assert.ok(service.get('isLoggedIn') === false, 'Not logged in');

    Ember.run(()=>{
        service.set('user', true);
    });

    assert.ok(service.get('isLoggedIn') === true, 'IS logged in');
});

test('can login', function(assert){
    assert.expect(0);

    var service = this.subject();
    Ember.run(()=>{
        service.login('uniqueID');
    });

    andThen(()=>{
        assert.ok(service.get('user'));
    });

});

Usando Ember 2.0.0-beta.5

Comentários muito úteis

Você está usando o serviço privado -routing , ele espera ter uma instância router inicializada e configurada. Este teste não faz isso, então você deve simular ou configurar o roteador.

Não me oponho a ajustar https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/services/routing.js#L37 um pouco para evitar esse erro (ele deve retornar false if get(this, 'router') for falsey) se você deseja enviar um PR, mas usar APIs privadas de uma forma não suportada não é um bug.

Todos 4 comentários

Você está usando o serviço privado -routing , ele espera ter uma instância router inicializada e configurada. Este teste não faz isso, então você deve simular ou configurar o roteador.

Não me oponho a ajustar https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/services/routing.js#L37 um pouco para evitar esse erro (ele deve retornar false if get(this, 'router') for falsey) se você deseja enviar um PR, mas usar APIs privadas de uma forma não suportada não é um bug.

Encerrando esta edição, mas eu ficaria feliz em revisar um PR.

Atrasado para o jogo, mas só quero mostrar como fiz para resolver esses problemas.

Basta substituir os métodos.

const service = this.subject({
    routing: {
      transitionTo() {
        return true;
      }
    }
})

Estou fazendo isso porque escrevi testes para testar diferentes rotas, também confio na equipe do ember para testar ember/service/routing.js

this.owner.unregister('service:router');
this.owner.register('service:router', mocks.routerService());

Uma maneira de fazer o stub sem falhar no caso de teste

Esta página foi útil?
0 / 5 - 0 avaliações