如何模拟另一个文件中定义的全局变量?

时间:2019-07-03 12:30:16

标签: javascript angular typescript unit-testing jasmine

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

是否不必在方法中封装此类全局变量,然后在方法而不是变量中进行模拟就可以了吗?我想让别人编写的应用程序代码保持不变。

1 个答案:

答案 0 :(得分:0)

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

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

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

并像这样实现存根。

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

注意:

如果要处理模拟HTTP调用,请使用HttpTestingController