3

i see lots of examples about how to unit test simple components in angular 2+, but when it comes to test components who use services, it becomes a nightmare to maintain the test bed providers and imports. how can i avoid it ?

for example i have myComponents, who uses myService, who uses HttpClient. To test myComponent i must setup the providers for myService and HttpClient. If i add an other service to the constructor of myService, i will have to edit ALL the testbeds of the cmoponents who use this service.

can't i tell the testbed to fetch the default dependencies for these modules?

1 Answer 1

1

The problem results from wrong testing methodology. Unit testing is about testing single units.

In this scenario

myComponents, who uses myService, who uses HttpClient. To test myComponent i must setup the providers for myService and HttpClient.

it is myComponent unit that it tested. This means that any other unit should be mocked or stubbed, including myService.

While this

fetch the default dependencies for these modules

is considered not unit but integration/e2e test.

Sign up to request clarification or add additional context in comments.

5 Comments

seems legit. however, is there a way to setup automatically stubs for this? a tool like angular cli that would make the mocks in the tests.
I don't think so. And you don't want to trust this to a machine. On the contrary, you need to skip stubs initially and make a test fail, so you clearly see what other units current unit depends on. myService stub itself can be simple jasmine.createSpyObj one-liner.
I totally disagree with you, for me testing component with mocked all depedencies is an anti-pattern (fabiopereira.me/blog/2010/05/27/…). To solve your problem @TyKayn you should have modules with all required depedencies for your components and setup your tests with that module (not inlining all of your depedencies). To make your tests easier you can use github.com/Pragmatists/ng-test-runner - there you have to pass only module to test your component - without exposing real depedencies of your component.
@wprzechodzen What are you conclusions based on? The fact that it was labeled as antipattern by some internet guy only means that it was labeled. Black box tests are integration tests (or functional, depending on the point of view). Not unit. They serve different purposes. This is what the answer says. Black box test that was failed can be very tricky to diagnose. 'Tautological' unit test is unambiguous, that's its purpose. When the app gets full coverage by unit tests and e2e tests, there's just no room for black box tests in general, they are redundant. The opposite isn't true for black box.
@EstusFlask, some time has passed since you wrote this, and your opinion may have changed, but I want to point out a change in best practices. Class-based unit testing leads to the "RGRR" anti-pattern, or "Red, Green, Refactor, Rewrite the test because you changed the object contract". Originally, the "unit" in unit testing was a "unit of isolation," not a class/method -- a test case with no side effects, that models an actual user requirement. They're more cumbersome to write -- like building a ship in a bottle -- but they aid in refactoring because the internal structure is not exposed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.