Gemäß der Jasmine-Dokumentation kann ein Mock wie folgt erstellt werden:
jasmine.createSpyObj(someObject, ['method1', 'method2', ... ]);
Wie stoppt man eine dieser Methoden? Wenn Sie beispielsweise testen möchten, was passiert, wenn eine Methode eine Ausnahme auslöst, wie würden Sie das tun?
javascript
jasmine
Adelin
quelle
quelle
andCallThrough
. Es ist nicht klar dokumentiert: /Antworten:
Sie müssen verketten
method1
,method2
wie EricG kommentierte, aber nicht mitandCallThrough()
(oderand.callThrough()
in Version 2.0). Es wird an die tatsächliche Umsetzung delegiert .In diesem Fall müssen Sie
and.callFake()
die Funktion, die Sie aufrufen möchten , verketten und übergeben (kann eine Ausnahme auslösen oder was auch immer Sie möchten):var someObject = jasmine.createSpyObj('someObject', [ 'method1', 'method2' ]); someObject.method1.and.callFake(function() { throw 'an-exception'; });
Und dann können Sie überprüfen:
expect(yourFncCallingMethod1).toThrow('an-exception');
quelle
.and.callFake()
,.and.callThrough()
,.and.returnValue()
jasmine.github.io/2.0/introduction.html#section-SpiesWenn Sie Typescript verwenden, ist es hilfreich, die Methode als umzuwandeln
Jasmine.Spy
. In der obigen Antwort (seltsamerweise habe ich keinen Repräsentanten für einen Kommentar):(someObject.method1 as Jasmine.Spy).and.callFake(function() { throw 'an-exception'; });
Ich weiß nicht, ob ich überentwickelt bin, weil mir das Wissen fehlt ...
Für Typescript möchte ich:
Ich fand das nützlich:
namespace Services { class LogService { info(message: string, ...optionalParams: any[]) { if (optionalParams && optionalParams.length > 0) { console.log(message, optionalParams); return; } console.log(message); } } } class ExampleSystemUnderTest { constructor(private log: Services.LogService) { } doIt() { this.log.info('done'); } } // I export this in a common test file // with other utils that all tests import const asSpy = f => <jasmine.Spy>f; describe('SomeTest', () => { let log: Services.LogService; let sut: ExampleSystemUnderTest; // ARRANGE beforeEach(() => { log = jasmine.createSpyObj('log', ['info', 'error']); sut = new ExampleSystemUnderTest(log); }); it('should do', () => { // ACT sut.doIt(); // ASSERT expect(asSpy(log.error)).not.toHaveBeenCalled(); expect(asSpy(log.info)).toHaveBeenCalledTimes(1); expect(asSpy(log.info).calls.allArgs()).toEqual([ ['done'] ]); }); });
quelle
todoService: {[key: string]: jasmine.Spy} = jasmine.createSpyObj(...); todoService.anyMethod.and....
- Sie müssen nicht jedes Mal auf Spy wirken.Winkel 9
Die Verwendung
jasmine.createSpyObj
ist ideal, wenn Sie eine Komponente testen, bei der ein einfacher Service injiziert wird. Zum Beispiel: Nehmen wir an, ich habe in meiner HomeComponent einen HomeService (injiziert). Die einzige Methode im HomeService ist getAddress (). Beim Erstellen der HomeComponent-Testsuite kann ich die Komponente und den Dienst wie folgt initialisieren:describe('Home Component', () => { let component: HomeComponent; let fixture: ComponentFixture<HomeComponent>; let element: DebugElement; let homeServiceSpy: any; let homeService: any; beforeEach(async(() => { homeServiceSpy = jasmine.createSpyObj('HomeService', ['getAddress']); TestBed.configureTestingModule({ declarations: [HomeComponent], providers: [{ provide: HomeService, useValue: homeServiceSpy }] }) .compileComponents() .then(() => { fixture = TestBed.createComponent(HomeComponent); component = fixture.componentInstance; element = fixture.debugElement; homeService = TestBed.get(HomeService); fixture.detectChanges(); }); })); it('should be created', () => { expect(component).toBeTruthy(); }); it("should display home address", () => { homeService.getAddress.and.returnValue(of('1221 Hub Street')); fixture.detectChanges(); const address = element.queryAll(By.css(".address")); expect(address[0].nativeNode.innerText).toEqual('1221 Hub Street'); }); });
Dies ist eine einfache Möglichkeit, Ihre Komponente mit zu testen
jasmine.createSpyObj
. Wenn Ihr Dienst jedoch über komplexere Methoden verfügt, würde ich empfehlen, anstelle von createSpyObj einen mockService zu erstellen. Zum Beispiel:providers: [{ provide: HomeService, useValue: MockHomeService }]
Hoffe das hilft!
quelle
Aufbauend auf der Antwort von @Eric Swanson habe ich eine besser lesbare und dokumentierte Funktion für meine Tests erstellt. Ich habe auch einige Typensicherheit hinzugefügt, indem ich den Parameter als Funktion eingegeben habe.
Ich würde empfehlen, diesen Code irgendwo in einer gemeinsamen Testklasse zu platzieren, damit Sie ihn in jede Testdatei importieren können, die ihn benötigt.
/** * Transforms the given method into a jasmine spy so that jasmine functions * can be called on this method without Typescript throwing an error * * @example * `asSpy(translator.getDefaultLang).and.returnValue(null);` * is equal to * `(translator.getDefaultLang as jasmine.Spy).and.returnValue(null);` * * This function will be mostly used in combination with `jasmine.createSpyObj`, when you want * to add custom behavior to a by jasmine created method * @example * `const translator: TranslateService = jasmine.createSpyObj('TranslateService', ['getDefaultLang']) * asSpy(translator.getDefaultLang).and.returnValue(null);` * * @param {() => any} method - The method that should be types as a jasmine Spy * @returns {jasmine.Spy} - The newly typed method */ export function asSpy(method: () => any): jasmine.Spy { return method as jasmine.Spy; }
Die Verwendung wäre wie folgt:
import {asSpy} from "location/to/the/method"; const translator: TranslateService = jasmine.createSpyObj('TranslateService', ['getDefaultLang']); asSpy(translator.getDefaultLang).and.returnValue(null);
quelle