speedskater / babel-plugin-rewire

A babel plugin adding the ability to rewire module dependencies. This enables to mock modules for testing purposes.
843 stars 90 forks source link

Test unexported functions #216

Closed LoiKos closed 5 years ago

LoiKos commented 5 years ago

Hello,

I create this issue because i wanted to test unexported functions from a module and it take me a few times to understand the process. I'm not quite sure what is the expected behavior of the plugin so i can't tell if it's a real bug or a limitation.

I use cjs and jest for my test.

container.mjs

import { BICcode } from './compagnies'

// ISO6346 table for letter value : [Source] https://en.wikipedia.org/wiki/ISO_6346
const calculationDict = {
  A: 10,
  B: 12,
  C: 13,
   ....
}

// Return BIC code from container number as String. /!\ Prefix isn't check so he may be invalid.
const getPrefix = code => {
  if (code.length < 4) return { err: 'Invalid Code length' }
  return code.slice(0, 4)
}

// Return Serial Number from container number as String. /!\ SN isn't check so he may be invalid.
const getSerialNumber = code => {
  if (code.length < 10) return { err: 'Invalid Code length' }
  return code.slice(4, 10)
}

// Return Check Digit from container number as Int
const getCheckDigit = code => {
  parseInt(code.charAt(code.length - 1))
}

and my test file container.spec.mjs :

import { __RewireAPI__ as ContainerAPI } from './container'

const getPrefix = ContainerAPI.__get__('getPrefix')
const getSerialNumber = ContainerAPI.__get__('getSerialNumber')
console.log(getPrefix)
console.log(getSerialNumber)

and when running this test, i get the following :

$ jest container
 FAIL  src/container/container.spec.mjs
  ● Test suite failed to run

    TypeError: Cannot read property '__get__' of undefined

      1 | import { __RewireAPI__ as ContainerAPI } from './container'
      2 | 
    > 3 | const getPrefix = ContainerAPI.__get__('getPrefix')
        |                   ^
      4 | const getSerialNumber = ContainerAPI.__get__('getSerialNumber')
      5 | 
      6 | console.log(getPrefix)

      at Object.<anonymous> (src/container/container.spec.mjs:3:19)

At this point i don't understand why it doesn't work but i tried to add the following in container.mjs :

// return all useful informations from container number ( Container number should contain 11 characters)
const getContainerInfo = code => {
  prefix: getPrefix(code)
  serialNumber: getSerialNumber(code)
  checkDigit: getCheckDigit(code)
  valid: checkDigitIsValid(code)
}

And it works ! So if i understand well that mean you need all functions to be used or exported to be testable ? But during development you can need to test them before using. Am i missing somethings ?

aonamrata commented 5 years ago

but then that is not how rewrite use to work. I was trying to migrate from rewrite to this plugin and keeps getting the same error for set or get

LoiKos commented 5 years ago

I figure out my problem sorry i forgot to explain and close this.

I Run into this issue cause i wasn't using any function i would to retrieve in an exported function. To get the plugin work you need to add an exported function, or object,or .... that use or references at least function you want to test.

Then they will appear in the hide variable : RewireAPI

For example :

the following will not work

   //myfunction.js
const funct1 = () => {}

export const funct2 = () => {}

//myfunction.test.js
import { funct2, __RewireAPI__ as FuncAPI } from './myfunction'
// FuncAPI will be null

this will work

   //myfunction.js
const funct1 = () => {}

export const funct2 = () => {
funct1()
}

//myfunction.test.js
import { funct2, __RewireAPI__ as FuncAPI } from './myfunction'
const funct = FuncAPI.__get__('funct1') // will receive the functions as expected
cjancsar commented 4 years ago

That doesn't seem right. This does not work. For me, RewireAPI is still empty.

ggihwa commented 4 years ago

@LoiKos Thanks! It works! @cjancsar Did you use none exported functions in exported functions? RewireAPI contains only these.