Sop*_*len 28 tdd amd requirejs typescript
我正在研究用TypeScript做TDD的可能性.如果我在TypeScript中编写我的测试,是否可以使import语句为我测试的类返回模拟?或者是用纯JavaScript编写测试并处理自己注入AMD的唯一可行方法?
Phi*_*ley 20
我在TypeScript中使用infuse.js进行依赖注入.
/// <reference path="definition/infusejs/infusejs.d.ts"/>
Run Code Online (Sandbox Code Playgroud)
this.injector = new infuse.Injector();
Run Code Online (Sandbox Code Playgroud)
this.injector.mapClass( 'TodoController', TodoController );
this.injector.mapClass( 'TodoView', TodoView );
this.injector.mapClass( 'TodoModel', TodoModel, true ); // 'true' Map as singleton
Run Code Online (Sandbox Code Playgroud)
export class TodoController
{
static inject = ['TodoView', 'TodoModel'];
constructor( todoView:TodoView, todoModel:TodoModel )
{
}
}
Run Code Online (Sandbox Code Playgroud)
它是基于字符串的,而不是基于类型的(因为在TypeScript中还不能实现反射).尽管如此,它在我的应用程序中运行良好.
Rem*_*sen 18
我开发了一个名为InversifyJS的IoC容器,它具有高级依赖注入功能,如上下文绑定.
您需要遵循3个基本步骤才能使用它:
注释API基于Angular 2.0:
import { injectable, inject } from "inversify";
@injectable()
class Katana implements IKatana {
public hit() {
return "cut!";
}
}
@injectable()
class Shuriken implements IShuriken {
public throw() {
return "hit!";
}
}
@injectable()
class Ninja implements INinja {
private _katana: IKatana;
private _shuriken: IShuriken;
public constructor(
@inject("IKatana") katana: IKatana,
@inject("IShuriken") shuriken: IShuriken
) {
this._katana = katana;
this._shuriken = shuriken;
}
public fight() { return this._katana.hit(); };
public sneak() { return this._shuriken.throw(); };
}
Run Code Online (Sandbox Code Playgroud)
绑定API基于Ninject:
import { Kernel } from "inversify";
import { Ninja } from "./entities/ninja";
import { Katana } from "./entities/katana";
import { Shuriken} from "./entities/shuriken";
var kernel = new Kernel();
kernel.bind<INinja>("INinja").to(Ninja);
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IShuriken>("IShuriken").to(Shuriken);
export default kernel;
Run Code Online (Sandbox Code Playgroud)
解决方案API基于Ninject:
import kernel = from "./inversify.config";
var ninja = kernel.get<INinja>("INinja");
expect(ninja.fight()).eql("cut!"); // true
expect(ninja.sneak()).eql("hit!"); // true
Run Code Online (Sandbox Code Playgroud)
最新版本(2.0.0)支持许多用例:
您可以访问https://github.com/inversify/InversifyJS了解更多相关信息
GitHub Typejector
使用新的TypeScript 1.5,可以使用注释方式
例如
@injection
class SingletonClass {
public cat: string = "Kitty";
public dog: string = "Hot";
public say() {
alert(`${this.cat}-Cat and ${this.dog}-Dog`);
}
}
@injection
class SimpleClass {
public say(something: string) {
alert(`You said ${something}?`);
}
}
@resolve
class NeedInjectionsClass {
@inject(SingletonClass)
public helper: SingletonClass;
@inject(SimpleClass)
public simpleHelper: SimpleClass;
constructor() {
this.helper.say();
this.simpleHelper.say("wow");
}
}
class ChildClass extends NeedInjectionsClass {
}
var needInjection = new ChildClass();
Run Code Online (Sandbox Code Playgroud)
对于问题案例:某些属性应该像下一个示例中那样实现伪接口(或抽象类).
class InterfaceClass {
public cat: string;
public dog: string;
public say() {
}
}
@injection(true, InterfaceClass)
class SingletonClass extends InterfaceClass {
public cat: string = "Kitty";
public dog: string = "Hot";
public say() {
alert(`${this.cat}-Cat and ${this.dog}-Dog`);
}
}
@injection(true, InterfaceClass)
class MockInterfaceClass extends InterfaceClass {
public cat: string = "Kitty";
public dog: string = "Hot";
public say() {
alert(`Mock-${this.cat}-Cat and Mock-${this.dog}-Dog`);
}
}
@injection
class SimpleClass {
public say(something: string) {
alert(`You said ${something}?`);
}
}
@resolve
class NeedInjectionsClass {
@inject(InterfaceClass)
public helper: InterfaceClass;
@inject(SimpleClass)
public simpleHelper: SimpleClass;
constructor() {
this.helper.say();
this.simpleHelper.say("wow");
}
}
class ChildClass extends NeedInjectionsClass {
}
var needInjection = new ChildClass();
Run Code Online (Sandbox Code Playgroud)
注意: 模拟注入应该在源代码之后定义,因为它重新定义了接口的类创建者
TypeScript 与 AMD 加载器(如 requirejs)配合得很好。如果配置正确,TypeScript 将输出完全符合 AMD 的 JavaScript。
在测试情况下,您可以配置 requirejs 来注入可测试的模块。