0

i'm facing a issue with my unit test, stuck completely, the code is simple, please need to understand what's going on, my stub is never called, the set seems to be correct, here the code:

let strategy = fixtures.load('strategy')
chai.use(chaiAsPromised)

describe.only('Spawn Order Job', () => {

  let getPositionsStub, createJobStub, daoStub,sandbox
  beforeEach(()=>{
    sandbox = sinon.createSandbox()
    daoStub = sandbox.stub(dao, 'updateActiveOrders').resolves(true) //async
    getPositionsStub = sandbox.stub(strategyModule, 'getPositions') //sync
    createJobStub = sandbox.stub(helpers, 'createJob') //sync
    createJobStub.returns(true)
    getPositionsStub.resolves([{fake:'t'}, {fake:'t'}])
  })

  afterEach(()=>{
    sandbox.restore()
  })
  //OK
  it('Should failed with no param, type error context', ()=> {
    const promise = spawnOrderJob()
    expect(promise).to.be.rejectedWith(TypeError)
  })


  //OK
  it('Should throw error timeout order', () => {
    getPositionsStub.resolves([{fake:'t'}, {fake:'t'}])
    strategy.lastDateOrder = new Date()
    const ctx = { state: {strategy, dashboard, position:null}}
    const action = {b: true, s: false}
    const promise = spawnOrderJob(action, ctx)
    expect(getPositionsStub.called).to.be.true
    expect(daoStub.called).to.be.false
    expect(createJobStub.called).to.be.false
    expect(promise).to.be.rejectedWith(ORDER_ERROR, 'Timeout between order not expired.')
  })

  //KO stub never called
  it.only('Should pass validation on buy', () => {
    strategy.lastDateOrder = 0
    const ctx = { state: {strategy, dashboard, position: null }}
    const action = {b: true, s: false}
    const promise = spawnOrderJob(action, ctx)
    expect(promise).to.be.fulfilled
    expect(getPositionsStub.called).to.be.true //ok
    expect(createJobStub.called).to.be.true //never callled ????
    expect(daoStub.called).to.be.true //never called ????
  })
})

Want to understand what's going now there, the call are correct imo, running with mocha 5.2

Helpers.js : function is described as follow:

async function spawnOrderJob(action, ctx) {
  try {
    const { strategy, dashboard, position } = ctx.state
    const {b, s} = action

    //check in case strategy context
    if (strategy) {
      //pass validation buy contnext
      if (b) {
        //this stub is working
        const positions = await strategyModule.getPositions(ctx)

        const { maxPosition } = strategy.allocatedBTC
        const { activeOrders, maxActiveOrders, timeBetweenOrder, lastDateOrder } = strategy

        debug('Active orders:', strategy.activeOrders)
        debug('Position:', positions.length)

        if (activeOrders >= maxActiveOrders)
          throw new ORDER_ERROR('Max active orders reach.')

        if (positions.length + activeOrders >= maxPosition)
          throw new ORDER_ERROR('Max positions reach.')

        if (!timeoutExpired(lastDateOrder, timeBetweenOrder))
          throw new ORDER_ERROR('Timeout between order not expired.')

        //increment active orders counter
        //stub fail, but not called at all
        await dao.updateActiveOrders(strategy, true)
      }

      //Sell context
      if (s) {
        if (!position)
          throw new ORDER_ERROR('No position to sell')
      }
    }
    //stub fail, but called internally
    return createJob(constants.DASHBOARD_CREATE_ORDER, {
      orderType: b ? 'BUY' : 'SELL',
      title: `Strategy create order ( ${ b ? 'BUY' : 'SELL'} )`,
      strategy,
      dashboard,
      position
    })
  } catch (e) {
    throw e
  }
}


function createJob(name, data){
  //shortcut queue.create (kue.js)
  return queue.c(name,data)
}

module.exports = {
  createJob,
  spawnOrderJob
}

DAO

const updateActiveOrders = async (strategy, increment) => {
      try {
       const s = await model.findOne({_id: strategy._id})
        if (!s) throw new Error('Strategy not found.')
        s.activeOrders = increment ? s.activeOrders+1 :s.activeOrders-1
        s.lastDateOrder = new Date()
        return await s.save()
      }catch(e){
        throw e
      }
    }

module.exports = {updateActiveOrders}
Arthur
  • 27
  • 7
  • I'd question whether any of these tests are actually genuinely passing at all, or whether you are getting false positives. You are dealing with promises and I don't think these tests are correctly testing those e.g. `expect` without `should` or `eventually`, as far as I can recall, won't wait for the Promise to resolve. There's not a lot to go on here e.g. what runner you are using? what does `spawnOrderJob()` look like? Where are `dao`, `strategyModule` and `helpers` defined? – James Nov 22 '18 at 11:37
  • Hey, well is not that the role of chai-as-promised, to resolve the promise itself ? the rejectWith works with other tests, but when i need to test the return values of the promise, i use await/async syntax in my test, but this is not the case here, i just want to check if my functions are called correctly, and changing behavior of the stubbed functions, i've just added the function to test for your information. thx for ur reply, maybe i'm tired, and can't see the evidence :) – Arthur Nov 22 '18 at 13:12
  • *"is not that the role of chai-as-promised, to resolve the promise itself?"* - only when you explicitly tell it to via `resolves`, and the test will only verify correctly if you use the specific promise-related expressions e.g. `expect(Promise.resolve(5)).to.equal(5)` will always fail, where as `expect(Promise.resolve(5)).to.eventually.equal(5)` would pass. Regardless, now that I've seen your code I can see why the test fails, and as expected the first tests are false positives as they aren't correctly testing the code. – James Nov 22 '18 at 14:25
  • The crux of your problem is very similar to another [answer](https://stackoverflow.com/questions/47796229/sinon-not-stubbing-on-module-exports/47796465#47796465) I've given before related to sinon. Have a read and let me know if you still need help. – James Nov 22 '18 at 14:30
  • Thx James, i understand now this subtility of nodejs require system, time to move on ES5 syntax maybe to avoid this kind of weird behave don't u think ? – Arthur Nov 22 '18 at 19:13
  • It's not really an ES6 problem, it's a general JS problem - you could replicate the same issue using pure JS. I would agree it's probably *easier* to fall into the traps with ES6 unless you fully understand why the syntax was introduced and what it does. Did my answer in the previous post help solve your problem? If so I can vote to close as a duplicate (and feel free to upvote said answer if it did :)) – James Nov 22 '18 at 20:00
  • 1
    Yes it does, that was the problem :) – Arthur Nov 23 '18 at 11:48
  • 1
    Possible duplicate of [Sinon not stubbing on module.exports](https://stackoverflow.com/questions/47796229/sinon-not-stubbing-on-module-exports) – James Nov 23 '18 at 12:42

0 Answers0