Не удается прочитать свойство '.then' неопределенных обещаний тестирования AngularJS - PullRequest
0 голосов
/ 10 октября 2019

У меня есть следующий код AngularJS, который я пытаюсь протестировать с помощью jasmine ad karma:

(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,Может кто-нибудь показать, как издеваться над этим обещанием?

...