-
Notifications
You must be signed in to change notification settings - Fork 726
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
Unit tests with mocha in watch mode cannot be run multiple times with @injectable decorator #563
Comments
Hi @orendin how are you importing "reflect-metadata" ? from the command line or form the app? The problem seems to be caused because the metadata is stored in the My guess is that the mocha watch mode is not cleaning the globals with each run. Can you please check if mocha has some setting force cleaning the globals? |
Hey @remojansen, super quick response time, thanks! It is imported inside the Hmmm... the globals in mocha. I have already done some research into this and could not find anything useful. But your hint helps to refine the search. Here we have a 'manual' way of trying to store and reset a global after tests are run in a global hook. This would mean trying to store a reference to the original Reflect and then resetting it back after the tests ran... I'll give this a shot, thanks! |
No peoblem @orendin, I'm quite sure that that is the problem. If you manage to reset the Reflect global it should work 😉 |
I can't seem to get a proper snapshot of the Reflect "Instance" to reset back to.
Then in the global after hook, I'm trying to resets the global Reflect back to the original:
But this doesn't do the trick. I don't have time to fiddle around with this any more at the moment and will keep the work-around for now. I'll come back to this later. Thanks! |
No problem, maybe the mocha guys can help. |
I have the same issue with |
I believe I have the same issue with parcel, which watches my React App and performs hot module reloading when source changes. 😞 |
FYI, I've created a PR to address this issue. The PR exposes a function to disable throwing an error on duplicate That said, I don't believe there's actually any benefit from throwing the error at all. Even if the developer has mistakenly applied an |
I have the same problem with nextJS in combination with a custom server watched bei nodemon. When i switch pages in nextJS or change anything in my sourcecode, i will receive this error. Has anyone found a solution to this? |
I had a PR which fixed the issue but I decided to close it since no one would merge it or give feedback even after I reached out to devs. |
Side: I’ve given up on using IOC libraries with JavaScript. I’ve found I rarely if ever need to swap out one implementation of some abstraction with another, other than when mocking services in tests, and because Jest makes mocking anything very simple I’ve found it makes IOC libraries for JS largely redundant, for my uses at least. |
Thanks for your feedback :) I am developing a large scale business application, so it is kind of a must-have :( I will check out typescript-ioc later today, maybe it will work better in combination with watch modes :) |
|
Hi all
I have a problem with my unit tests when I am trying to use Inversify with mocha on node. To be honest, I am not sure if it is an underlying mocha issue or if this could somehow be better handled by either my unit test setup or Inversify.
Expected Behavior
When I run my unit tests using mocha in watch mode
mocha --opts ./test/mocha.opts -w
,they should always result in the tests passing.
Current Behavior
When I run my unit tests using mocha in watch mode
mocha --opts ./test/mocha.opts -w
,the first time they work ok, any subsequent time Inversify throws the following exception:
Cannot apply @Injectable decorator multiple times.
Possible Solution
So I looked into the code in the annotation/injectable.js and spotted this:
Which, in turn, let me come up with this fugly work around:
This is obviously far from ideal since it's using magic strings taken out of your library.
Steps to Reproduce (for bugs)
I'll let the code speak in the context section. As described above, I am using mocha in watch mode to continuously run my tests when I change something, which I find a requirement to be productive:
mocha -w
,Context
As suggested in the documentation, I have created a inversify.config.ts file where I configure the container:
Here is a sample version of my test class:
In case it is relevant, I am creating es6 code, and using babel to execute mocha.
Mocha options file:
./src/**/*.spec.js --compilers js:babel-core/register --recursive
tsconfig.json:
It makes sense to only add the decorator once for the lifetime of the process, which works fine for the actual app. But in the case of unit tests with mocha in watch mode, I have no control over this (at least not that I can see). It seems, the decorator is kept in memory between the executions of the tests. Is there a way in Inversify to officially check if the decorator has been registered before? Or do you know of a way how I can "reset" the state in mocha with watch mode (I couldn't find one)?
Or is there something else I can do with my test setup to ensure that the external class is only decorated once (I mean other than my glorious work around)?
Your Environment
Versions used:
"inversify": "^4.1.0",
"reflect-metadata": "^0.1.10",
"babel-cli": "^6.24.1",
"babel-core": "^6.24.1",
"babel-loader": "^6.4.1",
"babel-preset-es2015": "^6.24.1",
"jasmine-core": "^2.6.2",
"mocha": "^3.4.2",
"mocha-junit-reporter": "^1.12.2",
Environment name and version (e.g. Chrome 39, node.js 5.4): nodejs v6.9.4
Operating System and version (desktop or mobile): Windows 7 (sadly)
Stack trace
The text was updated successfully, but these errors were encountered: