Home > Mobile >  How do you reset jasmine spy calls when using autoSpy with ng-mocks?
How do you reset jasmine spy calls when using autoSpy with ng-mocks?

Time:11-27

I am using ng-mocks for mocking and so far everything works OK with a few exceptions of some quirks.

I'm using autoSpy to spy every method automatically so I don't have to manually spy on functions. So according to the documentation, I've got, in my test.ts:

ngMocks.autoSpy('jasmine');

And I can use the spy method to test. For example, I've got something like this:

// in the main beforeEach() while setting up TestBed
myService: MyService = MockService(MyService);

describe(`When button A is clicked`, () => {
  beforeEach(() => {
    //button click code here
  });

  it(`Should call functionA one time`, () => {
    expect(myService.functionA).toHaveBeenCalled(); // This works ok
  });

});

// Further down in the same file
describe(`When button B is clicked`, () => {
  beforeEach(() => {
    //button click code here
    
    ngMocks.reset(); // I don't think this does what I think it does
  });

  it(`Should NOT call functionA`, () => {
    expect(myService.functionA).not.toHaveBeenCalled(); // This DOES NOT work. 
  });

});

The second time around, I'm trying to test that the function is not called with a different button, but the spy counts the previous call and fails. If I run just this test with jit, then it passes. Or if I move this test case above the first one, the first then it works. I can't just do mySpy.calls.reset() because I haven't assigned a spy manually. I tried myService.functionA.calls.reset() but there's an error - functoinA doesn't have calls method as it's not recognised as a spy.

Furthermore, if I put a debugger just before my expect.not.toHaveBeenCalled() and check through chrome dev window, I can run this myService.functionA.calls.reset() on the console and then it works fine.

How do I reset the all spy calls in ng-mocks please?

CodePudding user response:

I've never used ng-mocks, but I went through their documentation and repository. Have you tried using ngMock.autoSpy('reset') ?

If you check here: https://github.com/help-me-mom/ng-mocks/blob/dc91dd9948caf8208f9afeb9058b87a4eef9eecb/libs/ng-mocks/src/lib/mock-helper/mock-helper.auto-spy.ts

Passing reset should remove the last mock, so if you do something like:

beforeEach(() => {
  ngMocks.autoSpy('jasmine');
});

.
.
.

afterEach(() => {
  ngMocks.autoSpy('reset');
});

It might solve your issue :D

I hope that helps.

CodePudding user response:

ngMocks.autoSpy('jasmine'); simply calls jasmine.createSpy when a function / method should be mocked.

It means you don't need to reset it, because every test has its own objects and, therefore, its own new spies.

If your main beforeEach already contains MockService, nothing should be done extra. It creates a fresh mock for the service.

// in the main beforeEach() while setting up TestBed
const myService = MockService(MyService);

You need simply to remove ngMocks.reset();:

describe('root suite', () => {
  // in the main beforeEach() while setting up TestBed
  let myService: MyService

  beforeEach(() => myService = MockService(MyService));

  describe(`When button A is clicked`, () => {
    beforeEach(() => {
      //button click code here
    });

    it(`Should call functionA one time`, () => {
      expect(myService.functionA).toHaveBeenCalled(); // This works ok
    });
  });

  // Further down in the same file
  describe(`When button B is clicked`, () => {
    beforeEach(() => {
      //button click code here
    });

    it(`Should NOT call functionA`, () => {
      expect(myService.functionA).not.toHaveBeenCalled(); // This DOES NOT work. 
    });
  });
});

the code above ensures that each test has its own fresh instance of MyService with untouched spies.

Nevertheless, you can reset an existing spy as any other jasmine spy:

(myService.functionA as jasmine.Spy).calls.reset();
  • Related