Jasmine 2.0 async done() 和 angular-mocks inject() 在同一个测试 it()
Posted
技术标签:
【中文标题】Jasmine 2.0 async done() 和 angular-mocks inject() 在同一个测试 it()【英文标题】:Jasmine 2.0 async done() and angular-mocks inject() in same test it() 【发布时间】:2014-10-06 02:29:43 【问题描述】:我平时的测试用例是这样的
it("should send get request", inject(function(someServices)
//some test
));
Jasmine 2.0 异步测试应该是这样的
it("should send get request", function(done)
someAsync.then(function()
done();
);
);
如何在一个测试中同时使用 done 和 injection?
【问题讨论】:
【参考方案1】:这应该有效;我更新到 Jasmine 2.0 时遇到了同样的问题
it("should send get request", function(done)
inject(function(someServices)
//some async test
done();
)(); // function returned by 'inject' has to be invoked
);
【讨论】:
对我来说这行不通。inject
中的代码根本不会被调用。
@WhiteAngel,我上次遇到您描述的问题时,是因为 karma.conf.js 的 files
列表中缺少我的应用程序所需的一些依赖项。使用phantomJS
来调试它是不可能的,因为它提供的错误消息远远不够。如果您还没有弄清楚问题的根源,请尝试使用 Chrome 或 FF 作为测试浏览器。
这对我不起作用。 inject
的返回值是一个函数,需要调用。
@WhiteAngel @dokkaebi 在给出的代码示例中,立即调用从inject
返回的方法。这是超级重要的!如果你最后忘记了这两个括号,你的测试代码将不会被执行。【参考方案2】:
重要的注意事项是inject
调用后的括号。例如。
inject(function(someServices)
//some async test
done();
)(); <-- these brackets here important.
如果看inject
的类型:
export declare function inject(tokens: any[], fn: Function): () => any;
你可以看到它返回一个函数,所以你没有得到任何输出,因为你忘了调用这个函数!!
如果你仔细想想,它返回一个函数是有道理的,因为it
接受了一个函数!
所以额外的括号应该可以解决所有问题!
工作示例:
it('should allow you to observe for changes', function(done)
inject([GlobalStateService], (globalStateService: GlobalStateService) =>
globalStateService.observe("user", storageType.InMemoryStorage, (user: string) =>
expect(user).toBe("bla");
done();
);
globalStateService.write( user: "bla", storageType.InMemoryStorage);
)();
);
【讨论】:
我认为这可以作为答案。无论如何,评论都太长了。【参考方案3】:补充@Scott Boring 的答案和@WhiteAngel 的评论,他们提到从未调用过inject 中的代码。
这对我有用:
it("should send get request", function(done)
inject(function(someServices)
//some async test
done();
)();
);
【讨论】:
有道理。inject
的正常用法是将其返回值 (() => any
) 作为第二个参数传递给 it
,它由 jasmine 调用。所以我们必须调用inject
返回的函数才能运行!
我得到inject is not a function
这个【参考方案4】:
你可以这样写测试:
describe("Some service'", function ()
var service;
var data;
beforeEach(function (done)
module('app');
inject(function (someService)
service = someService;
);
service
.getData()
.then(function(result)
data = result;
done();
);
);
it('should return a result', function ()
expect(data).toBeDefined();
);
【讨论】:
【参考方案5】:对于 Angular 5.2.0:@scott-boring 的方法对我不起作用。起作用的是使用TestBed.get()
而不是inject()
来获取服务,如docs 中所述:
describe('TooltipComponent', () =>
let component: TooltipComponent;
let fixture: ComponentFixture<TooltipComponent>;
let myService: MyService;
beforeEach(async(() =>
const myServiceSpy = jasmine.createSpyObj('MyService', ['calc']);
TestBed.configureTestingModule(
declarations: [ MyComponent ],
providers: [
provide: MyService, useValue: myServiceSpy
]
)
.compileComponents();
myService = TestBed.get(MyService);
));
beforeEach(() =>
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
);
it('should render correctly', (done) =>
component.render();
setTimeout(() =>
expect(myService.calc).toHaveBeenCalled();
done();
, 1000);
);
【讨论】:
以上是关于Jasmine 2.0 async done() 和 angular-mocks inject() 在同一个测试 it()的主要内容,如果未能解决你的问题,请参考以下文章
如何在退出 Jasmine 测试之前测试 Observable 是不是已发布事件?