2016-10-02 3 views
0

Я изучаю Angular2. На страницах DI есть пример кода для издевательств. https://angular.io/docs/ts/latest/guide/dependency-injection.htmlПример кода: создание mocks в angular2

Что это значит

let mockService = <HeroService> {getHeroes:() => expectedHeroes } 

Это выглядит как определить mockService функцию из HeroService функции.

Что такое <HeroService>? Есть <HeroService> литье?

let expectedHeroes = [{name: 'A'}, {name: 'B'}] 
let mockService = <HeroService> {getHeroes:() => expectedHeroes } 

it('should have heroes when HeroListComponent created',() => { 
    let hlc = new HeroListComponent(mockService); 
    expect(hlc.heroes.length).toEqual(expectedHeroes.length); 
}); 

ответ

3

Чтобы добавить к JB Nizet's answer и дать небольшое объяснение причин, лежащих в основе кода.

машинопись использует Structural Type System. Это означает, что если он ошеломляет как утку, то ее можно считать утиной (точнее, быть совместимой с с утиной). Возьмем, к примеру

class Duck { 
    quack() { } 
} 

let duck = { 
    quack:() => {} 
} 

С duck имеет метод quack, вы можете передать его к чему-либо, ожидающей Duck, как

function doQuack(duck: Duck) { 
    duck.quack(); 
} 

doQuack(duck); 

машинопись достаточно умен, чтобы знать, что duck литерал объекта можно считать a Duck, даже если мы никогда не создадим экземпляр Duck с использованием duck = new Duck(). Это связано с тем, что структуры duck достаточно, чтобы быть совместимым с типом Duck, так как он соответствует структуре; причем структура представляет собой только один метод quack.

Если бы мы попытались ввести duck как Duck, и у нас не было метода quack, тогда мы получили бы ошибку компиляции.

let duck: Duck = { // compile error 
    mooo:() => {} 
}; 

let duck: Duck = { 
    quack:() => {} // OK 
} 

Это, как говорится, с, например, HeroSerivce имеет два метода, один, чтобы получить все герой, и один, чтобы получить герой по идентификатору.

class HeroService { 
    getHeroes(): Hero[] { .. } 
    getHeroById(id: number): Hero { .. } 
} 

И HeroComponent с конструктором, который принимает HeroService

class HeroComponent { 
    constructor(heroService: HeroService) {} 
} 

Теперь, если мы попытаемся пройти следующие

let mockService = { getHeroes:() => expectedHeroes } 

к HeroComponent конструктора, мы получим ошибку компиляции потому что mockService не соответствует структуре of HeroService. Он имеет только один метод getHeroes, когда структура фактически состоит из двух методов, getHeroes и getHero.

Поэтому, чтобы заставить компилятор просто принять его, мы «отбросим» его на <HeroService>.

Мы могли бы передать следующее (без «литья»), и оно будет работать, потому что оно соответствует структуре.

let mockService = { 
    getHeroes:() => expectedHeroes, 
    getHero: (id: number) => null 
}; 

- Подробнее из машинопись документации главы Type Compatibility

1

В JavaScript и TypeScript {a: b} является объектом литерала. Он определил объект с одним свойством a, имеющим значение b.

Так

{getHeroes:() => expectedHeroes } 

объект с одним свойством именем getHeroes, значение которого () => expectedHeroes() => expectedHeroes. Таким образом, значение является функцией без аргументов (()) и возвращает значение expectedHeroes.

<HeroService> называется type assertion:

Иногда вы будете в конечном итоге в ситуации, когда вы будете знать больше о стоимости, чем машинопись делает. Обычно это происходит, когда вы знаете, что тип какого-либо объекта может быть более конкретным, чем его текущий тип.

Утверждения типа - это способ рассказать компилятору «доверься мне, я знаю, что я делаю». Утверждение типа похоже на тип перевода на других языках, но не выполняет никакой специальной проверки или реструктуризации данных. Он не имеет эффекта runtime и используется исключительно компилятором.

Смежные вопросы