Javascript Unit testing - javascript

Recently I try to apply strict OO and testing to my application. And there are few things I would like to ask:
As javascript is not type restricted, for parameter input, do you need to write unit test to check if is null, undefined or different type?
Part of the last question, if yes, is it necessary to write unit test for constructor input parameter validation?
Should I try to apply strict OO to javascript OO. For example, all class should encapsulate their instance property (using var) and have getter/setter in closure instead?
From how I feel, trying to cover all the above will result in distraction and inefficient testing.
What is your suggestion?
Many thanks,

As javascript is not type restricted, for parameter input, do you need to write unit test to check if is null, undefined or different type?
It's up to you how defensive you want your code to be. If a requirement of your code is to gracefully handle nonsense arguments then you should write a test that tests that graceful handling. If you have code that handles it, you should have a test that covers it. If you don't have code to handle nonsense input, there isn't much reason to test it.
Part of the last question, if yes, is it necessary to write unit test for constructor input parameter validation?
Really, it's the same answer. If you have code that validates your inputs, you should have tests that cover that code.
Should I try to apply strict OO to javascript OO. For example, all class should encapsulate their instance property (using var) and have getter/setter in closure instead?
Javascript is not a traditional OO language. Only using strictly OO patterns would be doing yourself a disservice since JavaScript's most expressive features are around things on functional side of things. Having truly "private" member variables "using var", for instance, fundamentally changes the way you have to structure your code around those variables. This may not be a compromise worth making.
It's probably wise to architect a large codebase using primarily a class based approach. But don't be afraid to use functional features where appropriate. As long as you have the test coverage either way, of course. But this is primarily opinion at this point.

Related

How to check the inheritance relationship of ES6 classes in my project?

I use ES6 extends frequently in projects, sometimes I modify the parent class, but forget to check its child classes (as the increase of developers, things seemed to get worse). Maybe someone couldn't know if the class has been inherited anywhere.
Are there any tools or ways which could help me to check the inheritance relationship of classes?
Unit Tests
Unit test your code! If a superclass changes behavior, it will likely break a unit test, so you know you messed up and you know to correct the offending subclasses.
If it broke functionality in your application, but not one of your unit tests, then your unit test coverage is not good enough, or you've missed some scenarios.
That's the number one thing you should do before any kind of refactoring! Unit test, unit test, and again unit test!
Text Search
If you're using any fancy IDEs you could search through javascript files for something like "extends MyChangedSuperClasss", assuming you colleagues don't use an arbitrary number of spaces between the keyword and the class name.
If you're not using a fancy IDE try to find a file manager that offers text search functions.
(Can't comment yet, so posted as an answer.)
instanceof is as close as you're going to get.
Also, bug-a-lot isn't wrong. Unit testing would go a long way in preventing such regressions.

What is encapsulation in context of JavaScript?

What is encapsulation in context of JavaScript? I'm confused after reading this statement in mozilla web-site(link):
Encapsulation
In the previous example, Student does not need to know how the Person
class's walk() method is implemented, but still can use that method;
the Student class doesn't need to explicitly define that method unless
we want to change it. This is called encapsulation, by which every
class inherits the methods of its parent and only needs to define
things it wishes to change.
I've understood encapsulation as hiding class members, but in the example on the Mozilla site it seems to be simple inheritance.
It means that you don't have to be able to build the tools that you're using to use them.
It's makes programming a lot less stressful when you can abstract things like that away.
Have you ever used the alert() method in JavaScript?
I'm sure that you'd feel a bit overwhelmed if you had to care about how alert communicates with your browser, and how your browser communicates with your display and all the layers in-between.
You don't want to worry about the bezier curves used to render your fonts or how to implement the ok button, or all the other code that makes alert work. All you know is that you can write alert("txt") in JavaScript, and that a dialog box will appear.
walk is implemented in Person. Student isn't allowed to change how it's implemented, it can only override the function completely.
You could design a programming language that allows you to override parts of the parent function rather than the function as whole. This programming language has inheritance but not encapsulation.
Now of course if a child overrides part of a parent function, this means the child and parent implementations are coupled. This is generally considered bad practice. This is why most languages go so far as to enforce encapsulation, but it's not something you absolutely need.
Maybe a good analogy is a plugin mechanism. You can write plugins in different ways: use some event hooking or use clever inheritance but you can also do inline code replacement. Now before you think this is ridiculous, older versions of the popular forum software phpBB actually did this. You can imagine what happens if you install two plugins that might interfere, there's no telling what will happen!

How to describe function arguments in dynamic typed languages?

My question is more oriented toward Python, but it may also be about JavaScript or other scripting languages.
I usually develop with statically typed languages (Java, C++, ActionScript, ...).
I like to use from time to time Python, and I also need to sometimes use JavaScript. These are dynamic typed languages. Nothing wrong with that, but I usually have lots of headaches to understand which parameters are needed in a function or in a method. It happens even if it is my own code with some docstrings! Maybe because the eye has to look somewhere else than in the definition of the function.
Of course, the answer should be in the documentation. But sometimes it is not clear at all, or because of the use of duck typing the documentation may be itself hard to write ("the first parameter is a function which must have a quack() method and a feathers(arg) method where arg is a string"). What I would very like is a kind of argument description inside the language itself (even if it would be optionnal, like in ActionScript).
What are your best practices to unambiguously describe the arguments of a function/method?
What about creating a special decorator (if using Python) which purpose would be to check the type of data when we use it (but as it will be used at runtime and not at writing time, what would be the point anyway)?
Do you think it should not be an issue? That doing more than current docstring would confuse a developer, or that my mind is too static-typing oriented?
I don't know about Javascript, but Python has optional function annotations since version 3, which look like:
def haul(item: Haulable, *vargs: PackAnimal) -> Distance:
or:
def compile(source: "something compilable",
filename: "where the compilable thing comes from",
mode: "is this a single statement or a suite?"):
see the PEP for more information.
They are accessible at runtime and may even be used for type checking.
Why does duck typing make the documentation hard to write?
When ever you write a function, you write it assuming the arguments are of a particular type or confirm to a particular interface… So just document that.
For example, if you have a swim_in_pond(duck) method, there's no need to document "duck is expected to have quack(), swim(), and dive() methods" — in most cases, it's entirely sufficient to say "duck is an instance of Duck". Or, if it's important for you to document the "Duck-like" interface, I've found it helpful to declare a base class which serves as the documentation:
class DuckBase(object):
def quack(self):
""" Makes the duck quack. """
def swim(self):
""" Swims around.
Assumes the duck is already in water.
Updates the duck's position. """
def dive(self):
""" Dives either as deep as possible (either until the duck runs out of
air, or it hits the bottom of the pond). """

I want to stop using OOP in javascript and use delegation instead

After dabbling with javascript for a while, I became progressively convinced that OOP is not the right way to go, or at least, not extensively. Having two or three levels of inheritance is ok, but working full OOP like one would do in Java seems just not fitting.
The language supports compositing and delegation natively. I want to use just that. However, I am having trouble replicating certain benefits from OOP.
Namely:
How would I check if an object implements a certain behavior? I have thought of the following methods
Check if the object has a particular method. But this would mean standardizing method names and if the project is big, it can quickly become cumbersome, and lead to the java problem (object.hasMethod('emailRegexValidatorSimpleSuperLongNotConflictingMethodName')...It would just move the problem of OOP, not fix it. Furthermore, I could not find info on the performance of looking up if methods exist
Store each composited object in an array and check if the object contains the compositor. Something like: object.hasComposite(compositorClass)...But that's also not really elegant and is once again OOP, just not in the standard way.
Have each object have an "implements" array property, and leave the responsibility to the object to say if it implements a certain behavior, whether it is through composition or natively. Flexible and simple, but requires to remember a number of conventions. It is my preferred method until now, but I am still looking.
How would I initialize an object without repeating all the set-up for composited objects? For example, if I have an "textInput" class that uses a certain number of validators, which have to be initialized with variables, and a class "emailInput" which uses the exact same validators, it is cumbersome to repeat the code. And if the interface of the validators change, the code has to change in every class that uses them. How would I go about setting that easily? The API I am thinking of should be as simple as doing object.compositors('emailValidator','lengthValidator','...')
Is there any performance loss associated with having most of the functions that run in the app go through an apply()? Since I am going to be using delegation extensively, basic objects will most probably have almost no methods. All methods will be provided by the composited objects.
Any good resource? I have read countless posts about OOP vs delegation, and about the benefits of delegation, etc, but I can't find anything that would discuss "javascript delegation done right", in the scope of a large framework.
edit
Further explanations:
I don't have code yet, I have been working on a framework in pure OOP and I am getting stuck and in need of multiple inheritance. Thus, I decided to drop classes totally. So I am now merely at theoretical level and trying to make sense out of this.
"Compositing" might be the wrong word; I am referring to the composite pattern, very useful for tree-like structures. It's true that it is rare to have tree structures on the front end (well, save for the DOM of course), but I am developing for node.js
What I mean by "switching from OOP" is that I am going to part from defining classes, using the "new" operator, and so on; I intend to use anonymous objects and extend them with delegators. Example:
var a = {};
compositor.addDelegates(a,["validator", "accessManager", "databaseObject"]);
So a "class" would be a function with predefined delegators:
function getInputObject(type, validator){
var input = {};
compositor.addDelegates(input,[compositor,renderable("input"+type),"ajaxed"]);
if(validator){input.addDelegate(validator);}
return input;
}
Does that make sense?
1) How would I check if an object implements a certain behavior?
Most people don't bother with testing for method existance like this.
If you want to test for methods in order to branch and do different things if its found or not then you are probably doing something evil (this kind of instanceof is usually a code smell in OO code)
If you are just checking if an object implements an interface for error checking then it is not much better then not testing and letting an exception be thrown if the method is not found. I don't know anyone that routinely does this checking but I am sure someone out there is doing it...
2) How would I initialize an object without repeating all the set-up for composited objects?
If you wrap the inner object construction code in a function or class then I think you can avoid most of the repetition and coupling.
3) Is there any performance loss associated with having most of the functions that run in the app go through an apply()?
In my experience, I prefer to avoid dealing with this unless strictly necessary. this is fiddly, breaks inside callbacks (that I use extensively for iteration and async stuff) and it is very easy to forget to set it correctly. I try to use more traditional approaches to composition. For example:
Having each owned object be completely independent, without needing to look at its siblings or owner. This allows me to just call its methods directly and letting it be its own this.
Giving the owned objects a reference to their owner in the form of a property or as a parameter passed to their methods. This allows the composition units to access the owner without depending on having the this correctly set.
Using mixins, flattening the separate composition units in a single level. This has big name clash issues but allows everyone to see each other and share the same "this". Mixins also decouples the code from changes in the composition structure, since different composition divisions will still flatten to the same mixed object.
4) Any good resources?
I don't know, so tell me if you find one :)

The disadvantages of JavaScript prototype inheritance, what are they?

I recently watched Douglas Crockford's JavaScript presentations, where he raves about JavaScript prototype inheritance as if it is the best thing since sliced white bread. Considering Crockford's reputation, it may very well be.
Can someone please tell me what is the downside of JavaScript prototype inheritance? (compared to class inheritance in C# or Java, for example)
In my experience, a significant disadvantage is that you can't mimic Java's "private" member variables by encapsulating a variable within a closure, but still have it accessible to methods subsequently added to the prototype.
i.e.:
function MyObject() {
var foo = 1;
this.bar = 2;
}
MyObject.prototype.getFoo = function() {
// can't access "foo" here!
}
MyObject.prototype.getBar = function() {
return this.bar; // OK!
}
This confuses OO programmers who are taught to make member variables private.
Things I miss when sub-classing an existing object in Javascript vs. inheriting from a class in C++:
No standard (built-into-the-language) way of writing it that looks the same no matter which developer wrote it.
Writing your code doesn't naturally produce an interface definition the way the class header file does in C++.
There's no standard way to do protected and private member variables or methods. There are some conventions for some things, but again different developers do it differently.
There's no compiler step to tell you when you've made foolish typing mistakes in your definition.
There's no type-safety when you want it.
Don't get me wrong, there are a zillion advantages to the way javascript prototype inheritance works vs C++, but these are some of the places where I find javascript works less smoothly.
4 and 5 are not strictly related to prototype inheritance, but they come into play when you have a significant sized project with many modules, many classes and lots of files and you wish to refactor some classes. In C++, you can change the classes, change as many callers as you can find and then let the compiler find all the remaining references for you that need fixing. If you've added parameters, changed types, changed method names, moved methods,etc... the compiler will show you were you need to fix things.
In Javascript, there is no easy way to discover all possible pieces of code that need to be changed without literally executing every possible code path to see if you've missed something or made some typo. While this is a general disadvantage of javascript, I've found it particularly comes into play when refactoring existing classes in a significant-sized project. I've come near the end of a release cycle in a significant-sized JS project and decided that I should NOT do any refactoring to fix a problem (even though that was the better solution) because the risk of not finding all possible ramifications of that change was much higher in JS than C++.
So, consequently, I find it's riskier to make some types of OO-related changes in a JS project.
I think the main danger is that multiple parties can override one another's prototype methods, leading to unexpected behavior.
This is particularly dangerous because so many programmers get excited about prototype "inheritance" (I'd call it extension) and therefore start using it all over the place, adding methods left and right that may have ambiguous or subjective behavior. Ultimately, if left unchecked, this kind of "prototype method proliferation" can lead to very difficult-to-maintain code.
A popular example would be the trim method. It might be implemented something like this by one party:
String.prototype.trim = function() {
// remove all ' ' characters from left & right
}
Then another party might create a new definition, with a completely different signature, taking an argument which specifies the character to trim. Suddenly all the code that passes nothing to trim has no effect.
Or another party reimplements the method to strip ' ' characters and other forms of white space (e.g., tabs, line breaks). This might go unnoticed for some time but lead to odd behavior down the road.
Depending on the project, these may be considered remote dangers. But they can happen, and from my understanding this is why libraries such as Underscore.js opt to keep all their methods within namespaces rather than add prototype methods.
(Update: Obviously, this is a judgment call. Other libraries--namely, the aptly-named Prototype--do go the prototype route. I'm not trying to say one way is right or wrong, only that this is the argument I've heard against using prototype methods too liberally.)
I miss being able to separate interface from implementation. In languages with an inheritance system that includes concepts like abstract or interface, you could e.g. declare your interface in your domain layer but put the implementation in your infrastructure layer. (Cf. onion architecture.) JavaScript's inheritance system has no way to do something like this.
I'd like to know if my intuitive answer matches up with what the experts think.
What concerns me is that if I have a function in C# (for the sake of discussion) that takes a parameter, any developer who writes code that calls my function immediately knows from the function signature what sort of parameters it takes and what type of value it returns.
With JavaScript "duck-typing", someone could inherit one of my objects and change its member functions and values (Yes, I know that functions are values in JavaScript) in almost any way imaginable so that the object they pass in to my function bears no resemblance to the object I expect my function to be passed.
I feel like there is no good way to make it obvious how a function is supposed to be called.

Categories

Resources