【问题标题】:Angular Unit Testing - stub complex objectAngular Unit Testing - 存根复杂对象
【发布时间】:2020-05-01 18:09:33
【问题描述】:

在我的单元测试中,我必须创建具有大量属性的存根。

所以我会有这样的界面:

interface Person {
  id: string;
  name: string;
  age: number
  ...
}

然后我将必须创建一个实现此接口的对象并将一些值传递给每个属性。 Jasmine不是有一个函数,接收一个接口,返回一个带默认值的对象吗?

在上面的例子中,我会得到:

const stub: Person = createStubObj<Person>();
stub.id // ""
stub.name // ""
stub.getAge // 0

我做了一些研究,但没有发现任何有用的东西。

createSpyObj 似乎对我没有帮助,因为我没有任何想要监视的功能。对象只有属性。

当 HTTP 请求返回一个复杂对象(许多属性、嵌套属性)时,可能会发生这种情况。我想知道在这种情况下如何模拟该对象,而无需为每个属性指定值。

类似于这个库正在做的事情:https://www.npmjs.com/package/ts-auto-mock#usage

我想知道这是否也可以在 Jasmine 中实现,或者是否有更好的方法

【问题讨论】:

    标签: angular jasmine karma-jasmine angular-test


    【解决方案1】:

    我倾向于创建特定的模拟对象,这些对象可以使用 TestBed 提供者注册注入到被测组件中:

        TestBed.configureTestingModule({
            providers: [
                TestComponent,
                { provide: RealInterfaceType, useValue: new MockObjectType() }
            ]
        });
    

    然后您可以在模拟对象中定义适当的属性值。同样,您可以通过设置间谍来使用模拟对象作为依赖服务的响应:

        serviceSpy = jasmine.createSpyObj('SomeService', ['someFunction']);
        serviceSpy.someFunction.and.returnValue(new MockObjectType());
    

    对于http调用,我一般测试如下...

    let injector: TestBed;
    let service: TestService;
    let httpMock: HttpTestingController;
    const expectedResponse: TestObject = new TestObject();
    
    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule],
            providers: [
                TestService
        });
        injector = getTestBed();
        service = injector.get(TestService);
        httpMock = injector.get(HttpTestingController);
    });
    
    afterEach(() => {
        httpMock.verify();
    });
    
    describe('someFunction', () => {
        it('should return an Observable<UserAuthResponse>', () => {
            service.someFunction().subscribe(response => {
                expect(response).toBe(expectedResponse);
            });
            const req = httpMock.expectOne('http://the-expected-url');
            expect(req.request.method).toBe('GET');
    
            // return the static expected value
            req.flush(expectedResponse);
        });
    });
    

    这只是测试预期的 http 方法和 URL。

    【讨论】:

    • 感谢您的回复!如果您需要模拟来自非常复杂的 HTTP 服务的响应(具有多个属性、嵌套属性......),情况会怎样?您是否使用默认值定义每个属性?类似于这个库正在做的事情:npmjs.com/package/ts-auto-mock#usage 但我想知道这是否也可以在 Jasmine 中实现,或者是否有其他方法?
    • 用我用于测试 http 服务的代码更新了我之前的答案。不确定是否有更简单的方法。
    • 那个自动模拟库看起来很有用——我可能会在下次写一些 Angular 代码时尝试一下。
    猜你喜欢
    • 1970-01-01
    • 2012-04-06
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 2019-01-11
    相关资源
    最近更新 更多