86

Jasmine のドキュメントによると、モックは次のように作成できます。

jasmine.createSpyObj(someObject, ['method1', 'method2', ... ]);

これらのメソッドの 1 つをどのようにスタブしますか? たとえば、メソッドが例外をスローしたときに何が起こるかをテストしたい場合、どのようにしますか?

4

4 に答える 4

131

EricG がコメントしたように、連鎖する必要がありますが、method1(またはバージョン2.0 では) 連鎖する必要はありません。実際の実装に委譲しますmethod2andCallThrough()and.callThrough()

この場合and.callFake()、呼び出したい関数をチェーンして渡す必要があります(例外または必要なものをスローできます):

var someObject = jasmine.createSpyObj('someObject', [ 'method1', 'method2' ]);
someObject.method1.and.callFake(function() {
    throw 'an-exception';
});

そして、次のことを確認できます。

expect(yourFncCallingMethod1).toThrow('an-exception');
于 2012-11-30T15:19:17.623 に答える
23

Typescript を使用している場合は、メソッドを としてキャストすると便利Jasmine.Spyです。上記の回答で(奇妙なことに、コメントの担当者がいません):

(someObject.method1 as Jasmine.Spy).and.callFake(function() {
  throw 'an-exception';
});

オーバーエンジニアリングかどうかはわかりません。知識が不足しているからです...

Typescriptの場合、私は欲しい:

  • 基になる型からの Intellisense
  • 関数で使用されるメソッドだけをモックする機能

私はこれが便利だと思いました:

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']
        ]);
    });
});
于 2017-05-17T16:52:01.417 に答える
9

角度 9

jasmine.createSpyObj単純なサービスが注入されたコンポーネントをテストする場合に使用するのが理想的です。例: たとえば、HomeComponent に HomeService (注入済み) があるとします。HomeService の唯一のメソッドは getAddress() です。HomeComponent テスト スイートを作成するときに、コンポーネントとサービスを次のように初期化できます。

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');
    });
 });

これは、 を使用してコンポーネントをテストする簡単な方法jasmine.createSpyObjです。ただし、サービスにさらに複雑なロジックのメソッドがある場合は、createSpyObj の代わりに mockService を作成することをお勧めします。例えば: providers: [{ provide: HomeService, useValue: MockHomeService }]

お役に立てれば!

于 2020-06-12T17:57:14.243 に答える