我有以下AngularJS代码,正在尝试使用茉莉花广告业来测试:
(function() {
"use strict";
angular
.module("beckon.steel.beckonstandard.directives.templateDetails", [
// "beckon.steel.grid.services.beckonGridFactory",
// "beckon.steel.connectorTemplate.services.connectorTemplateService",
// "beckon.steel.dashboardTemplate.services.dashboardTemplateService",
// "beckon.steel.scorecards.services.scorecardTemplateService",
// "beckon.steel.channel.services.channelService",
// "beckon.steel.beckonstandard.services.beckonStandardEntityEnum",
// "beckon.steel.dimensions.dimensionService",
// "beckon.steel.formulabuilder.services.formulaTemplateService",
])
.directive("templateDetails", function(
beckonStandardEntityEnum,
connectorTemplateService,
dashboardTemplateService,
scorecardTemplateService,
channelService,
dimensionTemplateService,
formulaTemplateService,
$stateParams,
svg,
bnModalAlertService
) {
return {
templateUrl: "templateDetails",
restrict: "E",
scope: {
entity: "@",
baseState: "@",
},
controller: function($scope) {
$scope.backArrow = svg.ARROW_LEFT;
$scope.connector = null;
$scope.dashboard = null;
$scope.scorecard = null;
$scope.icon = svg.ARROW_LEFT;
const showAlert = function(successType, message) {
bnModalAlertService.clearAlerts().setAlert({
type: successType,
msgSafeHtml: message,
});
};
const onSuccess = () => showAlert("success", "Update successful");
const onFail = (err) => {
if (err.data && err.data.message) {
showAlert("error", `Update unsuccessful: ${err.data.message}`);
return;
}
showAlert("error", `Update unsuccessful: ${err.statusText}`);
};
if ($scope.entity === beckonStandardEntityEnum.CONNECTOR.type) {
$scope.backState = beckonStandardEntityEnum.CONNECTOR.uiRefState;
connectorTemplateService
.fetch($stateParams.id)
.$promise.then(function(connector) {
$scope.connector = connector;
});
$scope.updateConnector = function(connector) {
connectorTemplateService
.update($stateParams.id, connector)
.$promise.then(onSuccess)
.catch(onFail);
};
}
},
};
});
})();
到目前为止,我已经嘲笑了大多数依赖关系,但是在嘲笑connectorTemplateService承诺时遇到了麻烦。
fdescribe("templateDetails", () => {
"use strict";
let $scope;
let $compile;
let $rootScope;
let beckonStandardEntityEnum;
let connectorTemplateService;
let dashboardTemplateService;
let scorecardTemplateService;
let channelService;
let dimensionTemplateService;
let formulaTemplateService;
let $stateParams;
let svg;
let bnModalAlertService;
let $q;
let resolvedValue;
let deferred;
const getIsolatedScope = (element) => element.isolateScope() || element.scope();
beforeEach(module("beckon.steel.beckonstandard.directives.templateDetails"));
beforeEach(
module(($provide) => {
svg = jasmine.createSpy();
beckonStandardEntityEnum = {
CONNECTOR: {
type: "connectortype",
uiRefState: "connectorUiRefState",
},
DASHBOARD: {
type: "dashboardtype",
uiRefState: "dashboardUiRefState",
},
SCORECARD: {
type: "scorecardtype",
uiRefState: "scorecardUiRefState",
},
CHANNEL: {
type: "channeltype",
uiRefState: "channelUiRefState",
},
DIMENSION: {
type: "dimensiontype",
uiRefState: "dimensionUiRefState",
},
FORMULA: {
type: "formulatype",
uiRefState: "formulaUiRefState",
},
};
connectorTemplateService = {
fetch: () => {},
update: () => {},
}
bnModalAlertService = {
clearAlerts: () => ({
setAlert: jasmine.createSpy()
}),
};
$stateParams = {
id: "dummyid",
};
$provide.value("svg", svg);
$provide.value("beckonStandardEntityEnum", beckonStandardEntityEnum);
$provide.value("$stateParams", $stateParams);
$provide.value("connectorTemplateService", connectorTemplateService);
$provide.value("formulaTemplateService", formulaTemplateService);
$provide.value("scorecardTemplateService", scorecardTemplateService);
$provide.value("dimensionTemplateService", dimensionTemplateService);
$provide.value("channelService", channelService);
$provide.value("dashboardTemplateService", dashboardTemplateService);
$provide.value("bnModalAlertService", bnModalAlertService);
})
);
beforeEach(
inject((_$rootScope_, _$compile_, _$q_) => {
$compile = _$compile_;
$rootScope = _$rootScope_;
$scope = $rootScope.$new(true);
$q = _$q_;
})
);
describe("when entity matches CONNECTOR type", () => {
it("initializes correctly", () => {
// Arrange
const element = angular.element(
"<template-details entity='connectortype'>Here goes the template</template-details>"
);
spyOn(connectorTemplateService, "fetch").and.callFake((id) => {
let deferred = $q.defer();
deferred.resolve("the connector");
return deferred.promise;
});
spyOn(connectorTemplateService, "update").and.callFake((id) => {
let deferred = $q.defer();
deferred.resolve("success");
return deferred.promise;
});
// Act
$compile(element)($scope);
$scope.$digest();
const isolatedScope = getIsolatedScope(element);
isolatedScope.uiRefState = "connectorUiRefState";
const expectedValue = "the connector";
isolatedScope.updateConnector();
isolatedScope.$apply();
// Assertions
});
});
});
使用我模拟的方式(如在$ q角文档中所见),我收到错误cannot read property '.then' of undefined
我试图这样模拟
connectorTemplateService = {
update: (id, connector) => ({
$promise: {
then: (fn) => {
fn();
},
},
}),
fetch: (id) => ({
$promise: {
then: (fn) => {
fn("the connector");
},
},
}),
};
它适用于fetch
方法,但不适用于update
方法,因为它不是实际的承诺,并且update
方法有一个catch
块。谁能展示如何嘲笑这个诺言?