unit-testing - 在 Angular 中对 $sce.trustAsHtml 的输出进行单元测试

标签 unit-testing angularjs jasmine karma-runner

我正在用 Angular 编写一个 REST 应用程序,我想为它编写单元测试(当然!)。我有一个 Controller ,它从 json 中的 REST 服务获取博客文章列表,并将摘要放入 $scope,因此我可以在 View 中显示它们。

起初,博客文章只是显示为文本,即 <p>Blog body</p> ,而不是呈现为已解析的 HTML,直到我发现您可以使用 ng-bind-html结合 $sce service .现在,这在正确显示博客文章方面效果很好。

单元测试时出现问题。我正在尝试使用一些 HTML 模拟 json 响应,然后测试我的 Controller 是否正确处理 HTML。这是我的代码:

Controller

.controller( 'HomeCtrl', function HomeController( $scope, $http, $sce ) {
    $scope.posts = {};
    $http.get('../drupal/node.json').success(function (data) {
        var posts;
        posts = data.list;

        for(var i = 0; i < posts.length; i ++) {
            posts[i].previewText = $sce.trustAsHtml(posts[i].body.summary);
            posts[i].created = posts[i].created + '000'; // add milliseconds so it can be properly formatted 
        }
        $scope.posts = posts;
    });
})

单元测试
describe('HomeCtrl', function() {
    var $httpBackend, $rootScope, $sce, createController;

    beforeEach(inject(function ($injector) {
        // Set up the mock http service responses
        $httpBackend = $injector.get('$httpBackend');

        // Get hold of a scope (i.e. the root scope)
        $rootScope = $injector.get('$rootScope');
        // The $controller service is used to create instances of controllers
        var $controller = $injector.get('$controller');

        $sce = $injector.get('$sce');

        createController = function() {
            return $controller('HomeCtrl', {
                '$scope': $rootScope
            });
        };
    }));

    it('should get a list of blog posts', function() {
        var rawResponse = {
            "list": [
                {
                    "body": {
                        "value": "\u003Cp\u003EPost body.\u003C\/p\u003E\n",
                        "summary": "\u003Cp\u003ESummary.\u003C\/p\u003E\n"
                    },
                    "created": "1388415860"
                }
            ]};
        var processedResponse = [{
                "body": {
                    "value": "\u003Cp\u003EPost body.\u003C\/p\u003E\n",
                    "summary": "\u003Cp\u003ESummary.\u003C\/p\u003E\n"
                },
                "created": "1388415860000",
            previewText: $sce.trustAsHtml("\u003Cp\u003ESummary.\u003C\/p\u003E\n")
        }];

        $httpBackend.when('GET', '../drupal/node.json').respond(rawResponse);
        $httpBackend.expectGET("../drupal/node.json").respond(rawResponse);
        var homeCtrl = createController();
        expect(homeCtrl).toBeTruthy();
        $httpBackend.flush();
        expect($rootScope.posts).toEqual(processedResponse);
    });
});

当我通过 Karma 测试运行程序运行上述内容时,我得到以下响应:
Chrome 31.0.1650 (Windows) home section HomeCtrl should get a list of blog posts FAILED
    Expected [ { body : { value : '<p>Post body.</p>
    ', summary : '<p>Summary.</p>
    ' }, created : '1388415860000', previewText : { $$unwrapTrustedValue : Function } }          ] to equal [ { body
: { value : '<p>Post body.</p>
    ', summary : '<p>Summary.</p>
    ' }, created : '1388415860000', previewText : { $$unwrapTrustedValue : Function } }     ].

我怀疑问题是由于 $sce.trustAsHtml返回一个包含函数的对象,而不是字符串。

我的问题是,首先,我是否以正确的方式解决这个问题?

其次,如果是,我应该如何测试 $sce.trustAsHtml 的输出?

最佳答案

您必须在每次测试之前使用其提供程序禁用 $sce。

当 $sce 被禁用时,所有 $sce.trust* 方法只返回原始值而不是包装函数。

beforeEach(module(function ($sceProvider) {
  $sceProvider.enabled(false);
}));

it('shall pass', inject(function($sce){
  expect($sce.trustAsHtml('<span>text</span>')).toBe('<span>text</span>');
}));

在您的特定示例中,只需执行以下操作:
describe('HomeCtrl', function() {
  var $httpBackend, $rootScope, $sce, createController;

  beforeEach(module(function ($sceProvider) {
    $sceProvider.enabled(false);
  }));

  // rest of the file
});

关于unit-testing - 在 Angular 中对 $sce.trustAsHtml 的输出进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20946418/

相关文章:

ios - 如何在单元测试期间以编程方式编辑 iPhone 辅助功能设置?

javascript - 我可以将一个函数传递给另一个函数并调用该函数并具有依赖关系吗?

angularjs - 在指令属性上使用过滤器会导致 $digest 循环中的无限循环

angular - Angular 中的单元测试 : Mocking RxJS observable with Jasmine

javascript - 我如何使用 Sinon stub $(window).width() ?

unit-testing - 从 MSTest 迁移到 XUnit

c++ - 开始 Code::blocks 和 UnitTest++

javascript - 更改 ng 包含或定义默认 ui View

JavaScript - AngularJS promise 不返回任何东西

javascript - Angular httpBackend : No pending request to flush