如何在茉莉花中重置间谍?

Posted

技术标签:

【中文标题】如何在茉莉花中重置间谍?【英文标题】:How to reset a spy in Jasmine? 【发布时间】:2019-06-22 11:04:06 【问题描述】:

我有一个问题,我将模拟服务设置为间谍。

 mockSelectionsService = jasmine.createSpyObj(['updateSelections']);

然后我调用该存根方法两次,每次都在不同的测试中。问题是当我 expect() 带有 .toHaveBeenCalledWith() 的间谍时,toHaveBeenCalledWith 方法还包含它从第一个测试传递的参数,这在我的第二个测试中产生了误报。

我如何擦除/清除/重置 spyObject 以进行下一次测试,使其不再相信它已被调用?

服务/组件的初始化

  beforeEach(() => 
    mockSelectionsService = jasmine.createSpyObj(['updateSelections']);

    TestBed.configureTestingModule(
      declarations: [QuickSearchComponent, LoaderComponent, SearchComponent, SearchPipe, OrderByPipe],
      providers: [OrderByPipe, SearchPipe, SlicePipe, provide: SelectionsService, useValue: mockSelectionsService],
      imports: [FormsModule, HttpClientModule]
    );


    fixture = TestBed.createComponent(QuickSearchComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

    fixture.componentInstance.templates = mockTemplates;
    fixture.componentInstance.manufacturers = mockManufacturers;
  );

【问题讨论】:

在 beforeEach 中添加你的间谍对象初始化 我尝试在描述的 beforeEach() 中使用 mockSelectionsService = jasmine.createSpyObj(['updateSelections']); 重新初始化对象,但这似乎不起作用。我注意到似乎有很多不同的方法可以创建间谍,但 jasmine 文档/api 并没有完全给出答案。我已经更新了我的答案以在我的第一个 beforeEach() 中显示初始化 【参考方案1】:

const spy = spyOn(somethingService, "doSomething");

spy.calls.reset();

这将重置已对间谍进行的调用。这样您就可以在测试之间重用间谍。另一种方法是将测试嵌套在另一个 describe() 中,并将 beforeEach() 也放入其中。

【讨论】:

在我的 beforeEach() 中尝试 mockSelectionsService.calls.reset() 时得到 Cannot read property 'reset' of undefined 当你创建间谍对象时,你需要调用类似下面的东西来重置 mockSelectionsService.method.calls.reset();【参考方案2】:

类型 1:

var myService = jasmine.createSpyObj('MyService', ['updateSelections']);

myService.updateSelections.calls.reset();

类型 2:

var myService = spyOn(MyService, 'updateSelections');

myService.updateSelections.calls.reset();

注意:上面的代码是在 Jasmine 3.5 上测试的

【讨论】:

【参考方案3】:

默认返回值的mock服务可以在beforeEach()中设置,但是如果以后想改变mocked服务响应,不要在beforEach中调用fixture.detectChanges(),可以在每个spec中调用在应用所需的更改(如果有的话)之后,如果您想更改特定规范中的模拟服务响应,则将其添加到该规范之前的 fixture.detectChanges()

  beforeEach(() => 
    serviceSpy = jasmine.createSpyObj('RealService', ['methodName']);
    serviceSpy.methodName.and.returnValue(defaultResponse);

    TestBed.configureTestingModule(
      providers: [provide: RealService, useValue: serviceSpy ],
    ...
    )
    ...

    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    // do not call fixture.detectChanges() here
  );

  it('test something with default mocked service response', () => 
      fixture.detectChanges();
      ....
  );

  it('test something with a new mocked service response', () => 
      serviceSpy.methodName.and.returnValue(newResponse);
      fixture.detectChanges();
      ....
  );

【讨论】:

从 serviceSpy.and.returnValue(newResponse) 开始工作【参考方案4】:

添加到 Jelle 的答案中,如果您有 Cannot read property 'reset' of undefined when attempting mockSelectionsService.calls.reset(),请尝试:

const spy = spyOn(somethingService, "doSomething");
spy.mockRestore(); 

参考:jest spyon 演示:https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname

【讨论】:

以上是关于如何在茉莉花中重置间谍?的主要内容,如果未能解决你的问题,请参考以下文章

茉莉花间谍对进口模块(打字稿)

有啥方法可以根据参数修改 Jasmine 间谍?

Jasmine Spy:在returnValue中出错

如何在茉莉花中为可观察的 finally 块编写单元测试 - Angular 2

如何修复类型 'AsymmetricMatcher<any>' 不可分配给类型 '() => void'。在茉莉花/开玩笑

茉莉花钟如何工作?