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

esmock static import for classes not matching #303

Closed
brianzinn opened this issue May 15, 2024 · 3 comments
Closed

esmock static import for classes not matching #303

brianzinn opened this issue May 15, 2024 · 3 comments

Comments

@brianzinn
Copy link

I have nearly made the transition to ESM testing - >90% of tests are passing! Your library works really well - it has a good API and docs. I have an issue though setting up a test that requires seemingly an imported class that has a mismatch - I suspect due to the loader and how sinon is matching. I am using static imports for my Entities.

Maybe there is a way to get what esmock will give to my class with maybe a dynamic import in my tests after calling esmock? I'm trying to make the changes in a way where I only need to update the tests and not the code. That's probably what impressed me most about this library - was that for the transition I so far I have been updating tests only 😄

In my test setup with Sinon - I have something like (this worked before I switched to ESM):

import * as Entities from './entities';

fakeDataSource = sinon.createStubInstance(typeorm.DataSource);
// more setup
fakeEntityManager.getRepository.callsFake(getRepositoryStub);
const fakeAltPoAccountRepository = sinon.createStubInstance(typeorm.Repository);
getRepositoryStub.withArgs(Entities.MyEntity).returns(fakeAltPoAccountRepository);
//                             ^^ this seems to mismatch somehow
let sut = await esmock<ModuleUnderTest>({
      '../filepath',
      import.meta.url,
      {
        '../backend/data/DatabaseConnector': {
          getDataSource: stub().returns(fakeDataSource)
        }
      }
})

meanwhile `../filepath'

import * as Entities from '../src/entities'
const datasource = getDataSource(); // yay - this works.
const altPOAccountsRepository = dataSource.manager.getRepository(Entities.MyEntity);
//      ^^ this is undefined 

If I pass in the Entities from my test to the calling code it does work, so it has something to do with the classes being different. I don't quite understand the implications of the loader and how Sinon does that match comparison, but they are not matching now. I might end up needing a custom matcher - that's where I may look next, but I was hoping somebody had come across this before and had a solution.

node: v21.7.3

"esmock": "^2.6.5",
"mocha": "^10.4.0"

mocharc.json

{
  "$schema": "https://json.schemastore.org/mocharc.json",
  "extension": [
    "ts"
  ],
  "require": [
    "tsconfig-paths/register",
    "ts-node/register",
    "source-map-support/register",
    "reflect-metadata"
  ],
  "node-option": [
    "experimental-specifier-resolution=node",
    "loader=ts-node/esm",
    "no-warnings"
  ],
  "spec": "test/*.spec.ts",
  "timeout": 8000
}
@koshic
Copy link
Collaborator

koshic commented May 15, 2024

@brianzinn it's not so easy understand the whole setup, but! obviously, when you mock something with esmock, imports are comes from different module(s) (which is created on the fly) - so, object comparison by value, by using instanceof operator, etc. don't work as you may expect. In that particular case, if you want to compare some object exported from 'entities.js' with other object from the same file, you have mock that object with pre-defined value (doesn't matter which value - real object imported at the top of test file, or just unique symbol if code doesn't call object methods) in every test.

@brianzinn
Copy link
Author

thanks @koshic - I will try actually to pass them myself. I'm not sure why I didn't think of trying that. It's a bit of a paradigm shift thinking about the module loader. I can't try till later today - will report back. cheers.

esmock({
   ...,
   {
      ...
     '../pathToEntities': Entities
   }
)

@brianzinn
Copy link
Author

yes - that was it 🤦‍♂️ my tests are becoming more succinct as i make changes - this way of mocking guides me towards only mocking immediate dependencies.

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