代码之家  ›  专栏  ›  技术社区  ›  Chunbin Li

如何避免茉莉花抛出错误:XXX已经被刺探?

  •  1
  • Chunbin Li  · 技术社区  · 6 年前

    出身背景

    我有两个案例需要测试

    • 转到下一页时,表单应有效

      1. 设置表单有效值为true
      2. 呼叫 goToNextPage()
      3. 期望的结果是真实的
    • 填写选项信息然后转到下一页时,表单应有效

      1. 设置表单有效值为true
      2. 打开选项信息块
      3. 呼叫 goToNextPage()
      4. 期望的结果是真实的

    在第二个测试的步骤3中,当我通过 spyOnProperty 两次以上

    错误:“myPropertyName”已被监视

    我参考了过去几年的解决方案,并在下面写了一个临时解决方案。现在有没有更简单的方法来解决这个问题?


    • 设置 jasmine.getEnv().allowRespy(true);
    • 缓存第一个间谍,以后再使用

    class SamplePageHelper {
    
      private respyHelper = new JasmineRespyHelper();
    
      constructor(
        public samplePage: SamplePage
      ) {
    
      }
    
      fakeValid() {
        // spyOnProperty(this.samplePage, 'isValid').and.returnValue(true);
        this.respyHelper.spyOnProperty(this.samplePage, 'isValid').and.returnValue(true);
      }
    
    
    
    }
    // helper
    class JasmineRespyHelper {
    
      private cacheList = new Map();
    
      constructor() {
        jasmine.getEnv().allowRespy(true);
      }
    
      spyOnProperty < T > (object: T, property: keyof T, accessType ? : 'get' | 'set'): jasmine.Spy {
        const objectKey = object.constructor.toString().substring(0, 15);
        const cacheKey = `${objectKey}_${property}_${accessType || ''}`;
        //
        let spy = this.cacheList.get(cacheKey);
        const isNoCached = !spy;
        if (isNoCached) {
          spy = spyOnProperty(object, property, accessType);
          this.cacheList.set(cacheKey, spy);
        }
        //
        return spy;
      }
    }

    在线样本

    https://stackblitz.com/edit/jsamine-respy?file=src/test/sample.spec.ts

    describe('demo (no TestBed):', () => {
    
      let samplePage;
      let samplePageHelper;
      
      beforeEach(() => {
        samplePage = new SamplePage();
        samplePageHelper = new SamplePageHelper(samplePage);
      })
    
      it('shoud valid when write option fields then go to next page', () => {
        samplePageHelper.fakeValid();
         //
        samplePage.openOptionFieldBlock();
        //  new option field value will trigger form validator
    
        // ensure `goToNextPage()` can be executed needs to specify isValid to true again
        // Error: isValid has already been spied upon
        samplePageHelper.fakeValid();
    
    
        const isSuccess = samplePage.goToNextPage();
    
        expect(isSuccess).toBeTruthy();
      })
    
      it('shout valid when go to next page', () => {
        samplePageHelper.fakeValid();
    
        const isSuccess = samplePage.goToNextPage();
    
        expect(isSuccess).toBeTruthy();
      })
    });
    
    
    class SamplePage {
    
      private formService = new FormServiceStub();
    
      get isValid() {
        // trigger form field's validator
        // real code like this : formService.validationAll(); 
        return this.formService.valiationAll();
      }
    
      constructor() {
      }
    
      openOptionFieldBlock() {
        if (this.isValid) {
          // do someting 
        }
      }
    
      goToNextPage() {
        if (this.isValid) {
          // do someting
    
          const isSuccess = true;
          return isSuccess;
        }
    
        return false;
      }
    
      showOptionFields() {
        return true;
      }
    
    
    }
    
    
    // stub
    class FormServiceStub {
      valiationAll() {
        // it's have more codition in real code , return true for the demo
        return true;
      }
    }
    
    class SamplePageHelper {
    
      constructor(
        public samplePage: SamplePage
      ) {
    
      }
    
      fakeValid() {
        spyOnProperty(this.samplePage, 'isValid').and.returnValue(true);
      }
    
    
    
    }
    0 回复  |  直到 6 年前