加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何为angularjs/jasmine单元测试提供可重复使用的样本数据值

发布时间:2020-12-17 07:57:39 所属栏目:安全 来源:网络整理
导读:我想提供简单的常量值,如姓名,电子邮件等,以便在我的茉莉花单元测试中使用. 这里也提出了类似的问题:AngularJS + Karma: reuse a mock service when unit testing directives or controllers 在c#中,我将创建一个静态类来保存模拟数据的小片段.然后我可以在
我想提供简单的常量值,如姓名,电子邮件等,以便在我的茉莉花单元测试中使用.

这里也提出了类似的问题:AngularJS + Karma: reuse a mock service when unit testing directives or controllers

在c#中,我将创建一个静态类来保存模拟数据的小片段.然后我可以在整个单元测试中使用这些值,如下所示:

static class SampleData
{
    public const string Guid = "0e3ae555-9fc7-4b89-9ea4-a8b63097c50a";
    public const string Password = "3Qr}b7_N$yZ6";

    public const string InvalidGuid = "[invalid-guid]";
    public const string InvalidPassword = "[invalid-password]"; 
}

在使用Karma / Jasmine测试我的AngularJS应用程序时,我希望有同样的便利.

我知道我可以针对我的角度应用程序定义一个常量对象,我已经对我在真实代码中使用的常量执行此操作,如下所示:

myApp.constant('config',{apiUrl:'http://localhost:8082'})

我可以像这样添加另一个常量,但只包含用于我的单元测试的样本数据值,如下所示:

myApp.constant('sampleData',{email: 'sample@email.com'})

然后,我可以将模拟常量对象注入我的测试中,然后关闭,就像这样

describe 'A sample unit test',->
    beforeEach ->   module 'myApp'
    beforeEach inject ($injector) ->
        @sampleData = $injector.get 'sampleData'
        email = @sampleData.email
        # etc ...

然而这对我来说似乎有点可疑.我不希望我的生产代码包含仅我的单元测试所需的样本数据.

您如何通过可重复使用的样品数据值方便地提供角度/茉莉花单位测试?

谢谢

有两种方法可以做到这一点:

>监视函数调用并返回假值.
>创建模拟类(可能还有模拟数据以初始化它们)并在需要的地方加载它们

当你只需要打几个电话时,第一个就好了.为全班做这件事是不可持续的.

例如,假设您有一个构建一些特殊URL的服务.如果其中一个方法依赖于absUrl,你可以通过监视$location对象中的方法来伪造它:

describe('example') function () {
    beforeEach(inject(function () {
        spyOn($location,'absUrl').andCallFake(function (p) {
            return 'http://localhost/app/index.html#/chickenurl';
        });
    }));
it('should return the url http://www.chicken.org') ... {
    // starting situation
    // run the function
    // asserts
}

现在让我们假设您有一个设置服务,它封装了语言,主题,特殊路径,背景颜色,字体等数据,这些数据是使用对服务器的远程调用初始化的.
依赖于设置的测试服务将是痛苦的.你必须每次都用spyOn模拟一个大的组件.如果你有10个服务……你不想在所有服务中复制spyOn函数.

ServiceA使用设置服务:

describe('ServiceA',function () {
var settings,serviceA;

beforeEach(module('myapp.mocks.settings'));  // mock settings
beforeEach(module('myapp.services.serviceA')); // load the service being tested

beforeEach(inject(function (_serviceA_,_settings_) {
    serviceA = _serviceA_;
    settings = _settings_;
}));

容器
对于这个测试套件,所有对Settings服务的调用都将由mock处理,它具有与真实相同的接口,但返回虚拟值.
请注意,您可以在任何地方加载此服务.

(如果由于任何原因,您需要使用真正的实现,您可以在模拟之前加载真实的实现,并使用spyOn来处理该特定情况,以将调用委托给实际实现.)

通常,您将mocks模块放在app文件夹之外.我有一个带有单元测试的测试文件夹,e2e测试和带有angular-mocks.js文件的lib文件夹.我也把我的嘲笑放在那里.
告诉karma测试所需的文件:

files: [
      'app/lib/jquery/jquery-1.9.1.js','test/lib/jasmine-jquery.js','app/lib/angular/angular.js','app/lib/angular/angular-*.js','test/lib/angular/angular-mocks.js','test/lib/myapp/*.js',/* this is mine */
      'app/js/**/*.js','test/unit/**/*.js'
    ],

文件tests / lib / myapp.mocks.settings.js看起来就像任何其他模块一样:

(function () {
"use strict";

var m = angular.module('myapp.mocks.settings',[]);

m.service('settings',function () { ... })
})

第二个问题(可选):您希望快速更改虚拟值.在该示例中,设置服务在第一次实例化时从服务器获取对象.然后,该服务具有所有字段的getter.这是服务器的代理:不是每次需要值时发送请求,而是获取一堆请求并在本地保存它们.在我的应用程序中,设置在运行时不会在服务器中更改.

就像是:

1. fetch http://example.org/api/settings
2. var localSettings = fetchedSettings;
3  getFieldA: function() { return localSettings.fieldA; }

去污染全局命名空间.我创建了一个文件settings.data.js,内容如下:

var SETTINGS_RESPONSE = { fieldA: 42 };

模拟服务在工厂中使用此全局变量来实例化localSettings

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读