【问题标题】:How to mock global variables defined in another file?如何模拟另一个文件中定义的全局变量?
【发布时间】:2019-07-03 12:30:16
【问题描述】:

mockData.js

var userInfo = {
    URLs: {
        AppURL: "A" 
    },
    EncryptedBPC: "B"
};

karma.config.js

config.set({
    basePath: '',
    files:['mockData.js' ],
    .....

ComponentDetailsComponent

.....some imports
import { ComponentDetailsService } from '../component-details.service';
declare var userInfo: any;
@Component({
    .....more code

    rfxFilter() {     
        return userInfo.URLs.AppURL;
    }
}

规格:

describe('ComponentDetailsComponent', () => {
    let subject:any;
    let fixture: ComponentFixture<ComponentDetailsComponent>; 

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [ ComponentDetailsComponent ],
            providers: [{ provide: ComponentDetailsService, useClass: 
            ComponentDetailsServiceStub }],
        });
        fixture = TestBed.createComponent(ComponentDetailsComponent);
        subject = fixture.componentInstance;          
    });

    it('should return X', () => {
        subject.userInfo = {
            URLs: {
                AppURL: "X"
            },
            EncryptedBPC: "Y"
        };
        let result = subject.rfxFilter();
        expect(result).toBe("X");
    });   
});

输出:

ReferenceError: userInfo 未定义

我通过在组件内创建一个返回 userInfo 全局变量的方法使其工作。

getuserInfo():any{
    return userInfo;
}

并在规范中模拟该方法:

let m = {
    URLs: {
        AppURL: "mockvalueAppURL",
    },
    EncryptedBPC: "mockEncryptedBPC",
};
let spy = spyOn(subject, 'getuserInfo').and.returnValue(m);

是否可以模拟这样的全局变量而不必将其封装在方法中,然后模拟方法而不是变量?我希望在由其他人编写时保持应用程序代码不变。

【问题讨论】:

  • 您是否尝试过使用 behaviorSubject 或 replaySubject 来获取全局数据?这将使您可以从任何地方订阅它,并且它模拟它与模拟任何订阅相同。
  • @Ankit 这是其他人的现有代码。我只是为该代码编写单元测试。我不想对代码本身进行任何更改。

标签: javascript angular typescript unit-testing jasmine


【解决方案1】:

您无法访问任何其他文件的任何变量。你也不能模拟进口。您最好的朋友是 DI,因为您可以提供模拟类代替原始类进行测试。

您必须模拟提供数据的服务,而不是将数据放在单独的文件中。唯一的方法是导出 JSON 或对象并使用导出的对象。

TestBed.configureTestingModule({
    imports: [
    ],
    declarations: [
        ComponentDetailsComponent,
    ],
    providers: [
        {
            provide: RealService,
            useExisting: StubService,
        },
    ],
}).compileComponents();

并像这样实现存根。

class StubService implements Partial<RealService> {
    getuserInfo() {
        return { ...mockedData };
    }
}

注意:

如果您正在处理模拟 HTTP 调用,请使用 HttpTestingController

【讨论】:

  • 你是说不能模拟这个变量userInfo,除非我从单独的服务或带有组件的方法中获取它的值?
  • @Arbaaz 没错。但这似乎也不适合访问它,如果您有存根,存根应该有数据,如果您需要跨多个共享它,请将变量公开在一个单独的文件中,该文件将导入这些存根中。
猜你喜欢
  • 1970-01-01
  • 2017-04-25
  • 1970-01-01
  • 2022-08-03
  • 2021-09-23
  • 2013-01-04
  • 2015-05-11
  • 2019-03-15
  • 1970-01-01
相关资源
最近更新 更多