【问题标题】:How do i create a mock for this Role Service我如何为这个角色服务创建一个模拟
【发布时间】:2019-12-09 12:55:50
【问题描述】:

角色服务是我们应用程序的一部分。 我无法使用此服务,因为我无法模拟 BehaviourSubjects

import { Injectable } from '@angular/core';
import { ConstantService } from '../../services/constant/constant.service';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class RoleService {

  constants; // Variable to hold the constant JSON in asset folder

  constructor(private constantService: ConstantService) {
    this.constants = this.constantService.constantJson();
  }

  private isSiteAdmin = new BehaviorSubject<boolean>(null);
  public isSiteAdmin$ = this.isSiteAdmin.asObservable();

  private isPolicyApprover = new BehaviorSubject<boolean>(null);
  public isPolicyApprover$ = this.isPolicyApprover.asObservable();

  private isFtpApprover = new BehaviorSubject<boolean>(null);
  public isFtpApprover$ = this.isFtpApprover.asObservable();

  resetRoles() {
    this.isSiteAdmin.next(false);
    this.isPolicyApprover.next(false);
    this.isFtpApprover.next(false);
  }

  setUserRoles() {

    this.resetRoles();

    const roleList = this.constants.Roles;
    let userDetails;
    if (localStorage.getItem('currentUser') !== undefined) {
      userDetails = JSON.parse(localStorage.getItem('currentUser'));
    }

    if (userDetails.Roles.length > 0) {
      userDetails.Roles.forEach(role => {
        switch (role.RoleId) {
          case roleList.site_admin:
            this.isSiteAdmin.next(true);
            break;
          case roleList.policy_approver:
            this.isPolicyApprover.next(true);
            break;
          case roleList.ftp_approver:
            this.isFtpApprover.next(true);
            break;
          default:
            this.isUser.next(true);
        }
      });
    }
  }

}

报错Failed: roleService.isSiteAdmin$ is undefined 如何为这个服务创建一个模拟,以便我可以在组件中使用它

主页组件的规格文件

let component: MainPageComponent;
let fixture: ComponentFixture<MainPageComponent>;

fdescribe('MainPageComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        MainPageComponent,
        ControlLabelComponent,
        ControlTextboxComponent,
        ControlTextEditorComponent,
        ControlDropdownComponent,
        ControlUploadComponent,
        ControlImageViewerComponent,
        ControlHeaderComponent,
        ControlSubHeaderComponent,
        ControlMultilineBoxComponent,
        ControlExternalLinkerComponent,
        ControlLinkRepeaterComponent,
        ControlSyncAssociationComponent,
        ControlActorSubheaderComponent,
        LockContextComponent,
      ],
      providers: [
        { provide: Http, deps: [MockBackend] },
        { provide: ConstantService, useClass: ConstantServiceMock },
        { provide: LeftPanelService, useClass: ConstantServiceMock },
        { provide: RoleService, useClass: RoleServiceMock },
        { provide: MenuService, useClass: MenuService },
      ],
      imports: [
        HttpClientModule,
        RouterTestingModule,
        FormsModule,
        ModalModule.forRoot()
      ],
      schemas: [
          NO_ERRORS_SCHEMA,
          CUSTOM_ELEMENTS_SCHEMA
      ]
    }).compileComponents();
  }));

  beforeEach(async(() => {
    fixture = TestBed.createComponent(MainPageComponent);
    component = fixture.componentInstance;
  }));

  it('should create the app', () => {
    // component.constants.environment.production = true;
    expect(component).toBeTruthy();
  });

同样是说 roleService.isSiteAdmin$ 未定义。

添加了 TS 文件以便更好地理解

import { Component, OnInit, ViewChild } from '@angular/core';
import { ConstantService } from '../../services/constant/constant.service';
import { LeftPanelService } from '../../services/left-panel/left-panel.service';
import { RoleService } from '../../services/role/role.service';
import { MenuService } from '../../services/menu/menu.service';

@Component({
  selector: 'main-page',
  templateUrl: './main-page.component.html',
  styleUrls: ['./main-page.component.css']
})
export class MainPageComponent implements OnInit {

  //#region VARIABLES

  //#region Role Variables
  isSiteAdmin;
  isUser;
  isEditor;
  isProjectApprover;
  isAdmin;
  isUsecaseApprover;
  isActorApprover;
  isScenarioApprover;
  isPolicyApprover;
  isFtpApprover;

  isOtherMenuOptionDisabled;
  //#endregion

  messages; // Variable to hold the message JSON in asset folder
  constants; // Variable to hold the constant JSON in asset folder
  successPopupMessage: string; // used to show success message
  @ViewChild('successPopup') successPopup;
  errorPopupMessage: string; // used to show error message
  @ViewChild('errorPopup') errorPopup;
  @ViewChild('rightPanel') rightPanel;
  @ViewChild('whoApproved') whoApprovedPopup;
  @ViewChild('lockedInEditViewChild') lockedInEditViewChild;
  mainPageMenu;

  whoApprovedData;
  whoApprovedModalPopup;

  lockedInEditDataString: string;
  lockedInEditDataModalPopup;
  //#endregion

  //#region Constructor
  constructor(private constantService: ConstantService,
    private leftPanelService: LeftPanelService,
    public roleService: RoleService,
    private menuService: MenuService) {
    this.messages = this.constantService.messageJson();
    this.constants = this.constantService.constantJson();

    // get options
    menuService.mainPageMenu$.subscribe(menu => {
      this.mainPageMenu = menu;
    });

    // set the roles - added in the mail page constructor so that the values are available even if the page is refreshed
    this.roleService.setUserRoles();

    // set options
    this.menuService.setMainMenuOption();

    this.initializeMainPageMenu();

     // check site admin
     roleService.isSiteAdmin$.subscribe(isSiteAdmin => {
      this.isSiteAdmin = isSiteAdmin;
    });

    // check editor
    roleService.isEditor$.subscribe(isEditor => {
      this.isEditor = isEditor;
    });

    // check isUser
    roleService.isUser$.subscribe(isUser => {
      this.isUser = isUser;
    });

    // check isProjectApprover
    roleService.isProjectApprover$.subscribe(isProjectApprover => {
      this.isProjectApprover = isProjectApprover;
    });

    // check isUsecaseApprover
    roleService.isUsecaseApprover$.subscribe(isUsecaseApprover => {
      this.isUsecaseApprover = isUsecaseApprover;
    });

    // check isActorApprover
    roleService.isActorApprover$.subscribe(isActorApprover => {
      this.isActorApprover = isActorApprover;
    });

    // check isScenarioApprover
    roleService.isScenarioApprover$.subscribe(isScenarioApprover => {
      this.isScenarioApprover = isScenarioApprover;
    });

    // check isPolicyApprover
    roleService.isPolicyApprover$.subscribe(isPolicyApprover => {
      this.isPolicyApprover = isPolicyApprover;
    });

    // check isFtpApprover
    roleService.isFtpApprover$.subscribe(isFtpApprover => {
      this.isFtpApprover = isFtpApprover;
    });

    // check isAdmin
    roleService.isAdmin$.subscribe(isAdmin => {
      this.isAdmin = isAdmin;
    });

    this.disableOtherMenuOption();
    this.disableMenuForRoles();

    // who approved Modal Pop Up
    this.whoApprovedModalPopup = {
      whoApprovedModal: false,
      title: this.messages.LockPopup.WhoApproved,
      footerButtons: [
        { Text: 'Ok', event: 'ok', cssClass: 'footer-modal-popup-ok' },
      ],
    };

    // lock timeout Modal Pop Up
    this.lockedInEditDataModalPopup = {
      lockedInEditDataModal: false,
      title: this.messages.LockPopup.LockedInEditDetails,
      footerButtons: [
        { Text: 'Ok', event: 'ok', cssClass: 'footer-modal-popup-ok' },
      ],
    };
  }

  disableOtherMenuOption() {
    if (this.isSiteAdmin || this.isEditor) {
      this.isOtherMenuOptionDisabled = false;
    } else if (this.isUser || this.isProjectApprover || this.isScenarioApprover || this.isActorApprover
      || this.isUsecaseApprover || this.isPolicyApprover || this.isFtpApprover || this.isAdmin) {
      this.isOtherMenuOptionDisabled = true;
    }
  }
  //#endregion

  /**
   * Method to initialize Main Page Menu Options
   */
  initializeMainPageMenu() {
    // this.mainPageMenu = this.menuService.getMainPageMenu();

    /**
     * Method to disable all the remaining options other than view and create from FrameObject Menu
     */
    this.leftPanelService.getCurrentFrameObjType().subscribe(type => {
      this.mainPageMenu.dropdowns.forEach(dropDown => {
        if (dropDown.type !== type) {
          dropDown.options.forEach(option => {
            if (this.isOtherMenuOptionDisabled) {
              this.disabledExceptViewFrameObj(option);
            } else {
              if (option.key.indexOf('view') > -1 || option.key.indexOf('create') > -1) {
                option.isDisabled = false;
              } else {
                option.isDisabled = true;
              }
            }
          });
        } else {
          dropDown.options.forEach(option => {
            if (this.isOtherMenuOptionDisabled) {
              this.disabledExceptViewFrameObj(option);
            } else {
              option.isDisabled = false;
            }
          });
        }
      });
    });
  }

  disabledExceptViewFrameObj(option) {
    if (option.key.indexOf('view') > -1) {
      option.isDisabled = false;
    } else {
      option.isDisabled = true;
    }
  }

  disableMenuForRoles() {
    this.mainPageMenu.dropdowns.forEach(dropDown => {
      dropDown.options.forEach(option => {
        if (option.key.indexOf('view') > -1) {
          option.isDisabled = false;
        } else {
          if (this.isUser) {
            option.isDisabled = true;
          }
        }
      });
    });
  }
  //#endregion

  //#region Init
  ngOnInit() { }
  //#endregion

  /**
    * Method to hide the who approved pop up
    */
  okWhoApprovedModalPopup() {
    this.whoApprovedPopup.hide();
  }

  /**
    * Method to hide the lock time out pop up
    */
  okLockedInEditDataModalPopup() {
    this.lockedInEditViewChild.hide();
  }

}

在我们的应用程序中,大多数地方都使用了角色服务。 因此,如果解决了一页..其他将变得容易。 请仔细查看

【问题讨论】:

  • 请在您调用 roleService.isSiteAdmin$ 时包含出现错误的文件
  • 在规范文件中。
  • { 提供:RoleService, useClass: 'MOCKFILEHERE'},我应该把模拟文件放在这里,但我无法得到我应该为主题编写模拟的内容

标签: angular unit-testing rxjs observable karma-jasmine


【解决方案1】:

在你的规范文件中创建一个模拟类:

class MockRoleService {
 // include any properties AND/OR functions used by the components
 isSiteAdmin$: Observable<boolean>;
 resetRoles() {}
 setUserRoles() {}
 ...
}

在规范文件提供程序中声明您的模拟服务:

{ provide: RoleService, useClass: MockRoleService }

【讨论】:

  • 不,它仍然无法设置 isSiteAdmin$ undefined 的值
  • 请包含规范文件
  • 添加了注入此服务器的组件的规范文件
  • 您能否也包含组件 html/ts 以了解您如何调用您的服务?
  • 老板也加了ts文件
猜你喜欢
  • 2017-04-06
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
  • 1970-01-01
  • 2021-02-23
  • 2023-03-22
  • 1970-01-01
  • 2021-10-10
相关资源
最近更新 更多