can you restore original functionality when using jest's automock? - jestjs

i would like to use automock, and then restore a single function to it's original value, test it, and then re-mock it. this seemed like a good way to prevent any functions from unexpectedly being called, but this doesn't seem possible.
or is there another way to whitelist individual functions to making assertions on them...
a VERY contrived example...
foo.js
export function foo() {
return 'FOO'
}
foo.test.js
jest.enableAutomock()
import { foo } from 'foo.js'
foo.mockRestore()
expect(foo()).toBe('FOO')

Related

Run code before NestJs Decorators initialization

Are there ways to get data and save from another microservice before decorator initialization? As I understand decorators initialize even before bootstrap function is called
Decorators evaluate to regular JS code that is evaluated when the file is required. The only way to run something before the decorator, is to have that something higher in the file, or before that file is even required in another script. It'd be like having
export const foo = () => {
console.log('foo');
}
console.log('Here we are exporting foo');
And wanting to run something before the console.log('Here we are exporting foo'). The only way is to have what you want to run higher up in the file, or before this file is every required

Is there a way to test functions with Jasmine without exposing them?

I have a utils.js file with some generic utility functions. I use module.exports to expose some of the functions while keep the rest hidden.
module.exports = {
utils_1: function_1,
utils_2: function_2
};
Suppose there are other functions, namely function_3 and function_4 that I would like not to expose, yet I want to test with Jasmine. The only way I can currently do it is by exposing them with the rest of the functions and writing my test suites as usual.
Is there a way to test some functions via Jasmine while not exposing them?
The only thing I can think of is creating a different javascript file containing (and exposing) function_3 and function_4, require that file in my utils.js and at the same time test the new file with Jasmine, but this would split my original file in two (and the same would apply for all other similar files).
function_3 and function_4 are used inside function_1 and function_2, right? So, do you really need to unit test it? I would not. But other people might think the contrary.
Here is my example
// utils.js
function function_3(obj) {
obj.a = 3;
return obj;
}
function function_4(obj) {
obj = function_3(obj); // invoke function_3
obj.b = 4;
return obj;
}
module.exports = { utils_4: function_4 };
The test:
const { utils_4 } = require('utils');
describe('test 1', () => {
it('should pass', () => {
const obj = utils_4 ({});
expect(obj.a).toBeDefined();
expect(obj.a).toEqual(3);
expect(obj.b).toBeDefined();
expect(obj.b).toEqual(4);
});
});
It should pass, right? See that I only test function_4, but, if I change the implementation of function_3 in a way that brakes my test, the test will detect it.
If we change function_3 to
function function_3(obj) {
obj.c = 3;
return obj;
}
The test will fail.
This is an awful example but it is just illustrative. Take the good part of it. But again, other people might think the contrary and will go with an approach to test function_3 directly. Use a coverage lib to see what is covered by your tests.
Hope it helps
Your private / unexposed functions are used within your exported functions, are they not? Thereby, they are tested implicitly as soon as you write all the test cases for your public / exposed functions.
Exposing functions or writing tests on private functions is missing the goal of unit tests: Testing the public interface.
Think of private / unexposed methods as implementation details. You should not write tests for those, as the private methods are abstracting the implementation detail. It becomes tedious and over-complicated to have tests break because some internal behavior changed slightly.
You should be able to refactor or rewrite private functions at a whim, yet as long as they public interface is fulfilled, your tests shall remain green.
It may make sense to create a new module for your function_3 and function_4, depending on what they are doing for you. If I discover, that I want to test something internally, that's a sign to make it into its own module, with its own public interface.
So I'd say that your intention of moving the functions into a different JavaScript file is actually the right idea. (Yet you may realize that here only function_3 needs to be exposed, whereas function_4 can still be hidden).

Creating a yieldable Node Module/Object

I am trying to create a Node module (using harmony) that upon loading by another module/application, has to be yielded to so that things in it's construct can be executed and loaded before any of it's exposed functions can be called.
The issue I am having is that I cannot seem to yield to the internal function that is being executed, using module.exports. An example would help.
module.exports = function*(s_id){
console.log('loading the module lets it execute up till here');
if (!(this instanceof Tester)) return yield new Tester();
}
function* Tester(){
console.log('but we never execute this generator function');
}
Tester.prototype = {
model : function*(){
// other functions
}
}
It's been stumping me for hours now! I feel like the solution is super simple but I cannot seem to wrap my head around it. I have tried to simply make the Tester() function the export, but am still having the same issue. Why can't I seem to yield to the Tester() function?
Also, what may an alternative be to this approach? I want to maintain the Object nature of the module so that the module can be loaded with different inputs, such as the s_id variable/object in the example above.
a Node module (using harmony) that upon loading by another module/application, has to be yielded to so that things in it's construct can be executed and loaded before any of it's exposed functions can be called
Don't do that. Generators are not made for asynchrony. yield doesn't do what you want here. A module is not "yielded" to await something in it to load. yield is magic, but not async magic.
If you must use an asynchronous module loading process, export a promise for your actual module. That is a standard interface for something to await, and can be consumed using a standardized approach that does not rely on internals of your module.
You still can use yield syntax for constructing that promise, just use your favorite coroutine library.
return yield new Tester();
…
function* Tester(){…}
Uh oh. Well yes, apparently it is possible to call generator functions as constructors. But believe me, it is not what you want. A constructor for an arbitrary object should return that object, instead of an iterator (just like it shouldn't return a promise). If some of your object methods are generator methods, that's fine, but your constructor should be not.
If you really want to use a generator function in your code like that (and it's not meant to be a constructor), you
will need to yield* the iterator you've created (tester()) instead of yielding it
must not overwrite its .prototype property like you did, as that causes the iterator to malfunction. (Of course you should never do that at all, even though most of the time it works)

Is it ever OK to write an NPM module that sets module.exports to a generator function?

If you want to publish a module that has sequenced IO, is it ever OK to write,
./sequenced_actions.js
module.exports = function * () {}
Thereby permitting something like,
co( function * {
yield require('./sequenced_actions');
} )();
if you want your modules to reach the largest audience possible, just write them in promises. hopefully node v0.12 will have native promises, so this will make things easier
Yes, it's okay to do that.
Generator function is just an ordinary function under the hood. And since node.js allows an arbitrary value to be exports object of a module, you can export whatever you want there.

Models with dependency injection in Nodejs

What is the best practice for injecting dependencies into models? And especially, what if their getter are asynchronous, as with mongodb.getCollection()?
The point is to inject dependencies once with
var model = require('./model')({dep1: foo, dep2: bar});
and call all member methods without having to pass them as arguments. Neither do I want to have each method to begin with a waterfall of async getters.
I ended up with a dedicated exports wrapper that proxies all calls and passes the async dependencies.
However, this creates a lot of overhead, it's repetitive a lot and I generally do not like it.
var Entity = require('./entity');
function findById(id, callback, collection) {
// ...
// callback(null, Entity(...));
};
module.exports = function(di) {
function getCollection(callback) {
di.database.collection('users', callback);
};
return {
findById: function(id, callback) {
getCollection(function(err, collection) {
findById(id, callback, collection);
});
},
// ... more methods, all expecting `collection`
};
};
What is the best practice for injecting dependencies, especially those with async getters?
If your need is to support unit testing, dependency injection in a dynamic language like javascript is probably more trouble than it's worth. Note that just about none of the modules you require from others are likely to use the patterns for DI you see in Java, .NET, and with other statically compiled languages.
If you want to mock out behavior in order to isolate specific units of code for testing, see the 'sinon' module http://sinonjs.org/. It allows you to dynamically swap in/out interceptors that can either spy on method calls or replace them altogether. In practice, you would write a mocha test where you require your module, then require a module that's leveraged in your code. Use sinon to spy or stub a method on that module and as a result, you can isolate your code.
There is one scenario where I've not been able to completely isolate 3rd party code with sinon, and this is when the act of require()ing a module executes some behavior that you don't want to run in your test. For that scenario, I made a super simple module called 'mockrequire' https://github.com/mateodelnorte/mockrequire that allows you to provide an inline mock to be required instead of the actual module. You can provide a mock that uses spy or stub from sinon and have the same syntax and patterns as all the rest of your tests.
Hopefully this answers the underlying question from your post. ;)
In very simple situations, you could simply export a function that modifies objects in your file scope and returns your actual exports object, but if you want to inject more variably (i.e. for more than one use from your app) it's generally better to create a wrapper object like you have done.
You can reduce some overhead and indentation in some situations by using a wrapper class instead of a function returning an object.
For instance
function findById(id, callback, collection) {
// ...
// callback(null, Entity(...));
};
function Wrapper(di) {
this.di = di;
}
module.exports = Wrapper; // or do 'new' usage in a function if preferred
Wrapper.prototype.findById = function (id, callback) {
// use this.di to call findById and getCollection
}, // etc
Other than that, it's not a whole lot you can do to improve things. I like this approach though. Keeps the state di explicit and separate from the function body of findById and by using a class you reduce the nesting of indentation a little bit at least.

Resources