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

replacing a nested dependency does not get reset correctly #293

Closed
jliebrand opened this issue Oct 16, 2017 · 2 comments
Closed

replacing a nested dependency does not get reset correctly #293

jliebrand opened this issue Oct 16, 2017 · 2 comments

Comments

@jliebrand
Copy link

I am trying to replace a 'leaf' dependency, which seems to work fine the first time, but then fails the second time. It would appear that some global state is left behind, and whilst td.reset does reset some state, it looks like the td.when state is not cleared?

Repro case:

// brakedisc.js
class BrakeDisc {

  squeeze () {
    // Success
    return true;
  }
}

export default BrakeDisc;
// brake.js
import BrakeDisc from './brakedisc';

class Brake {

  constructor () {
    this.brakeDisc = new BrakeDisc();
  }

  applyPressure () {
    return this.brakeDisc.squeeze();
  }
}

export default Brake;
// car.js
import Brake from './brake';

class Car {

  constructor () {
    this.brake = new Brake();
  }

  stop () {
    return this.brake.applyPressure();
  }
}

export default Car;
// car.test.js
import td from 'testdouble';
import { assert } from 'chai';

describe('car', function() {

  let myCar;

  beforeEach(function() {
    const BreakDisc = td.replace('./brakedisc').default;
    td.when(BreakDisc.prototype.squeeze()).thenReturn(false);

    const Car = require('./car').default;
    myCar = new Car();
  });

  afterEach(function() {
    td.reset();
  });

  it('should fail', () => {
    assert.isFalse(myCar.stop());
  });

  it('should fail again', () => {
    assert.isFalse(myCar.stop());
  });

});

Which results in:

  car
    ✓ should fail
    1) should fail again


  1 passing (288ms)
  1 failing

  1) car
       should fail again:
     AssertionError: expected undefined to be false
      at Context.<anonymous> (car.test.js:25:12)

It would look like the BreakDisc is still replaced in the second test, but the td.when is no longer adhered to?

@jliebrand
Copy link
Author

Ok, I can get this to work with the following test... Which is not as per the examples, and makes me wonder about the td.replace state. But at least the td.reset does seem to clear things out (the call count is as expected).

// car.test.js
import td from 'testdouble';
import { assert } from 'chai';

describe('car', function() {

  let myCar;
  let BreakDisc = td.replace('./brakedisc').default;;

  beforeEach(function() {
    td.when(BreakDisc.prototype.squeeze()).thenReturn(false);

    const Car = require('./car').default;
    myCar = new Car();
  });

  afterEach(function() {
    td.reset();
  });

  it('should fail', () => {
    assert.isFalse(myCar.stop());
  });

  it('should fail again', () => {
    assert.isFalse(myCar.stop());
  });

});

@searls
Copy link
Member

searls commented Oct 16, 2017

I suspect the cause for this is that quibble doesn't know it shouldn't be caching the Brake module. Because BrakeDisc is a transitive dependency of Car we don't specify what would happen in this case because in our practice we only ever replace direct dependencies and not transitive ones

(Reason being: the test should be describing the contract between the Car and the Brake and not mucking with the internal implementation of the Brake's dependencies as it shouldn't have reason to know about them and be coupled to them.)

As a result I'd consider this case to be unsupported/undefined behavior but I wouldn't be opposed to it working, either. The right place to look into implementing this is the quibble module: https://github.com/testdouble/quibble

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