Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

thenThrow does not work if stub passed down #319

Closed
gotenxds opened this issue Dec 27, 2017 · 3 comments
Closed

thenThrow does not work if stub passed down #319

gotenxds opened this issue Dec 27, 2017 · 3 comments

Comments

@gotenxds
Copy link

gotenxds commented Dec 27, 2017

Hi, for some reason (context?) when using thenThrow, the method wont throw if it is being passed to another method

Example:

let someObjtWithThrowMethod = td.object(originalObj);
when(someObjtWithThrowMethod.throw(anything()).thenThrow(new Error('HO GOD NO');

//....

it('w/e', () => {
   someMethod(someObjtWithThrowMethod.throw) // This method calles the given method.

   verify(someObjtWithThrowMethod.throw(anything)) // true! but no exception is thrown!
}


it('w/e2', () => {
   someObjtWithThrowMethod.throw() // throws!
}
@searls
Copy link
Member

searls commented Dec 27, 2017

Can you please provide a reproducible example? This doesn't seem right and the example isn't enough to debug with

@gotenxds
Copy link
Author

gotenxds commented Dec 27, 2017

running on mac node 8-lts

const td = require('testdouble');

describe.only('', () => {
  function funcCaller(func) {func()}
  
  const obj = td.object({throw: () => {}});
  it('Shold throw error', () => {
    td.when(obj.throw()).thenThrow(new Error('HAAAAA'));
    
    try {
      obj.throw();
    }
    catch(e) {
      console.log('YAY'); // works as expected
    }
  });

  it('Shold throw error2', () => {
    td.when(obj.throw()).thenThrow(new Error('HAAAAA'));
    
    try {
      funcCaller(obj.throw);
    }
    catch(e) {
      console.log('YAY'); // never gets here
    }
  });
});

@searls
Copy link
Member

searls commented Jan 8, 2018

In test runners like mocha & jasmine, it's unsafe to execute any per-test code inside of a describe callback. The describe callback is invoked before any tests in the entire suite run (tools invoke these immediately to build out the tree/structure/plan of what will be tested), whereas before and it callbacks are called on a per-test basis and can be regarded as "test-time execution".

As a result, you should definitely have the td.object() assignment inside of the test itself, whether in a before hook or the it. What you have currently will invoke before any tests in any other file, and anything one test does with it will impact the other test. In addition, anyone that calls td.reset() (which should be set in a global after hook) could influence its state and affect whether your test works, which you don't want.

Changed example:

describe.only('', () => {
  function funcCaller(func) {func()}
  
  it('Shold throw error', () => {
    const obj = td.object({throw: () => {}});

    td.when(obj.throw()).thenThrow(new Error('HAAAAA'));
    
    try {
      obj.throw();
    }
    catch(e) {
      console.log('YAY'); // works as expected
    }
  });

  it('Shold throw error2', () => {
    const obj = td.object({throw: () => {}});

    td.when(obj.throw()).thenThrow(new Error('HAAAAA'));
    
    try {
      funcCaller(obj.throw);
    }
    catch(e) {
      console.log('YAY'); // never gets here
    }
  });
});

@searls searls closed this as completed Jan 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants