How do you test a private function in angular 2 ?
class FooBar {
private _status: number;
constructor( private foo : Bar ) {
this.initFooBar();
}
private initFooBar(){
this.foo.bar( "data" );
this._status = this.fooo.foo();
}
public get status(){
return this._status;
}
}
The solution I found
Put the test code itself inside the closure or Add code inside the closure that stores references to the local variables on existing objects in the outer scope.
Later strip out the test code using a tool. http://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/
Please suggest me a better way to solve this problem if you have done any?
P.S
Most of the answer for similar type of question like this one doesn't give a solution to problem, that's why I'm asking this question
Most of the developer say you Don’t test private functions but I don't say they are wrong or right, but there are necessities for my case to test private.
This route I take is one where I create functions outside the class and assign the function to my private method.
Now I don't know what type of OOP rules I am breaking, but to answer the question, this is how I test private methods. I welcome anyone to advise on Pros & Cons of this.
Do not write tests for private methods. This defeats the point of unit tests.
Example
The test for this method should not need to change if later the implementation changes but the
behaviour
of the public API remains the same.Don't make methods and properties public just in order to test them. This usually means that either:
As most of the developers don't recommend testing private function, Why not test it?.
Eg.
YourClass.ts
TestYourClass.spec.ts
Thanks to @Aaron, @Thierry Templier.
As many have already stated, as much as you want to test the private methods you shouldn't hack your code or transpiler to make it work for you. Modern day TypeScript will deny most all of the hacks that people have provided so far.
Solution
TLDR; if a method should be tested then you should be decoupling the code into a class that you can expose the method to be public to be tested.
The reason you have the method private is because the functionality doesn't necessarily belong to be exposed by that class, and therefore if the functionality doesn't belong there it should be decoupled into it's own class.
Example
I ran across this article that does a great job of explaining how you should tackle testing private methods. It even covers some of the methods here and how why they're bad implementations.
https://patrickdesjardins.com/blog/how-to-unit-test-private-method-in-typescript-part-2
Note: This code is lifted from the blog linked above (I'm duplicating in case the content behind the link changes)
Before AfterI'm with you, even though it's a good goal to "only unit test the public API" there are times when it doesn't seem that simple and you feel you are choosing between compromising either the API or the unit-tests. You know this already, since that's exactly what you're asking to do, so I won't get into it. :)
In TypeScript I've discovered a few ways you can access private members for the sake of unit-testing. Consider this class:
Even though TS restricts access to class members using
private
,protected
,public
, the compiled JS has no private members, since this isn't a thing in JS. It's purely used for the TS compiler. Therefor:You can assert to
any
and escape the compiler from warning you about access restrictions:The problem with this approach is that the compiler simply has no idea what you are doing right of the
any
, so you don't get desired type errors:You can use array access (
[]
) to get at the private members:While it looks funky, TSC will actually validate the types as if you accessed them directly:
To be honest I don't know why this works. It seems that array brackets don't enforce access restrictions, but type inference gives you full type safety. This is exactly what I think you want for your unit-testing.
Here is a working example in the TypeScript Playground.
The answer by Aaron is the best and is working for me :) I would vote it up but sadly I can't (missing reputation).
I've to say testing private methods is the only way to use them and have clean code on the other side.
For example:
It' makes a lot of sense to not test all these methods at once because we would need to mock out those private methods, which we can't mock out because we can't access them. This means we need a lot of configuration for a unit test to test this as a whole.
This said the best way to test the method above with all dependencies is an end to end test, because here an integration test is needed, but the E2E test won't help you if you are practicing TDD (Test Driven Development), but testing any method will.