{"id":27963190,"url":"https://github.com/windmillcode/unit_testing_in_angular","last_synced_at":"2026-01-23T20:04:20.791Z","repository":{"id":132081459,"uuid":"422611075","full_name":"WindMillCode/Unit_Testing_In_Angular","owner":"WindMillCode","description":"learning unit testing in angular","archived":false,"fork":false,"pushed_at":"2021-10-29T17:59:19.000Z","size":165,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-05-07T19:58:22.495Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WindMillCode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-10-29T14:44:26.000Z","updated_at":"2021-10-29T17:59:22.000Z","dependencies_parsed_at":"2023-07-12T09:15:59.227Z","dependency_job_id":null,"html_url":"https://github.com/WindMillCode/Unit_Testing_In_Angular","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/WindMillCode/Unit_Testing_In_Angular","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WindMillCode%2FUnit_Testing_In_Angular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WindMillCode%2FUnit_Testing_In_Angular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WindMillCode%2FUnit_Testing_In_Angular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WindMillCode%2FUnit_Testing_In_Angular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WindMillCode","download_url":"https://codeload.github.com/WindMillCode/Unit_Testing_In_Angular/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WindMillCode%2FUnit_Testing_In_Angular/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28699372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T17:25:48.045Z","status":"ssl_error","status_checked_at":"2026-01-23T17:25:47.153Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-07T19:58:21.808Z","updated_at":"2026-01-23T20:04:20.785Z","avatar_url":"https://github.com/WindMillCode.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Course Introduction\n\n## Mocking\n* testing a single unit of code in isolation\n* component depends on many deps\n* __dummies__ - just fill a place \n* __stub__ -object has controllable behavior\n* __spies__ keeps track how many times object called, which object and parameters are used\n    * used the most\n* __true mock__ - complex test I was called, I was called x times, with x paramaeters\n\n## Unit Testing Types\n* __isolation__ -  test component only\n* __integration__ - test component with its template\n\n\n## Tools\n* karma - run tests in browser\n* jasimne - test framework\n\n### Additional\n* mocha,jest\n* Sinon - if jasmine is not good enough\n\n## First unit test\n* use describe describe it block for 3 logical steps\n[first test](ngUnitTestingDemo\\src\\app\\first-test.spec.ts)\n* use npm test in order to test \n* open on localhost:9876\n\n## Writing Good unit tests\n* __aaa pattern__ - arrange, act,assert\n* set inital state, change state , make sure new state is correct\n* DAMP -repeat yourself if necessary\n* should look around much to understand the it\n    * keep critical setup in the it\n\n\n#  Isolated Unit Testing\n\n## test a pipe\n* just remove the @Component and test as a regular class\n* [strength pipe](ngUnitTestingDemo\\src\\app\\strength\\strength.pipe.ts)\n* test if transform takes number and returns a string\n* test every exit point \n\n# Test A Service\n* [message service](ngUnitTestingDemo\\src\\app\\message.service.spec.ts)\n* make sure you have an act and assert, resetting state is part of act because its not inital state\n\n\n# Test A Component\n* [heroes component](ngUnitTestingDemo\\src\\app\\heroes\\heroes.component.spec.ts)\n* you need a fake service\n* you need a delete method of the mocked service\n* can also use lifecycle hooks to help out\n* avoid running test by using xit\n\n## State Based\nsince heroes componet uses getHeroes', 'addHero', 'deleteHero' from heroservice\nmake a mock like this\n```ts\n  beforeEach(() =\u003e {\n    HEROES = [\n      {id: 1, name: 'SpiderDude', strength: 8},\n      {id: 2, name: 'Wonderful', strength: 24},\n      {id: 3, name: 'SuperDude', strength: 55}\n    ]\n    mockHeroService = jasmine.createSpyObj(['getHeroes', 'addHero', 'deleteHero']);\n    component = new HeroesComponent(mockHeroService);\n  });\n```\n\n* also you need the method to have the return value of the type\nso if mockSerivce.getHeroes returns Observable\u003cboolean\u003e do like this\n\n```ts\nmockHeroService.deleteHero.and.returnValue(of(true));\n```\n## Interatction test\n\n* use this to check if a specfic method has been called\n```ts\nexpect(mockHeroService.deleteHero).toHaveBeenCalled()\nexpect(mockHeroService.deleteHero).toHaveBeenCalledWith(HEROES[2]);\n```\n\n# Shallow Integration Tests\n* make sure keep browser is open\n* needed detectChanges in integration tests\n* fixture.detectChanges(); may call ngOnInit\n\n## TestBed\n\n[hero componenet](ngUnitTestingDemo\\src\\app\\hero\\hero.component.shallow.spec.ts)\n\n* TestBed.configureTestingModule refer to app.module\n* use schemas to angular how to process its HTML\n    * NO_ERRORS_SCHEMA, means to silience things like routerLink and missing routermodule provide\n* fixture.nativeElement is a dom HTMLElement\n* after you set properties related to HTML bindings use     fixture.detectChanges(); to update bindings\n\n## Debug Element\n* there is query, queryAll\n```ts\nfixture.debugElement.query(By.css('a'))\nfixture.debugElement.queryAll(By.css('a'))\n```\n\n* there is By from angular-platform browser\nmainly By.css,By.directive\n\n## Complex Shallow Integration\n* [heroes component](ngUnitTestingDemo\\src\\app\\heroes\\heroes.component.spec.ts)\n\n* there are the HeroService and the children compoents you need to worry about\n* mock the injected service\n```ts\n    mockHeroService = jasmine.createSpyObj(['getHeroes', 'addHero', 'deleteHero']);\n    TestBed.configureTestingModule({\n      declarations: [HeroesComponent],\n      providers: [\n        {provide: HeroService, useValue: mockHeroService}\n      ]\n    });\n```\n\n* dont use NO_ERROS_SCHEMA here because you are testing the html tests is correct\n* mock the child component\n\n```ts\n  @Component({\n    selector: 'app-hero',\n    template: '\u003cdiv class=\"badge\"\u003e{{hero.id}}\u003c/div\u003e {{hero.name}}',\n  })\n  class FakeHeroComponent { // could be real hero but its obvious its fake\n    @Input() hero: Hero;\n  }\n\n\n// in before Each\nmockHeroService = jasmine.createSpyObj(['getHeroes', 'addHero', 'deleteHero']);\n    TestBed.configureTestingModule({\n      declarations: [HeroesComponent,FakeHeroComponent],\n      providers: [\n        {provide: HeroService, useValue: mockHeroService}\n      ]\n    });\n// \n```\n## Lists of elements\n\n# Deep Integration Tests\n * use fixture.detectChanges(); for change detection in beforeEach\n * will run ngOnit for all child components\n\n * [heroes component](ngUnitTestingDemo\\src\\app\\heroes\\heroes.component.spec.ts)\n\n # Integration Testing of Services\n * [hero service](ngUnitTestingDemo\\src\\app\\hero.service.spec.ts)\n\n\ncontroller.expectOne, dones'nt make a http request happen on its on\nit also expects a request to be made\nalso expect the test not to make any xhr than the string arg\n\nreq.flush , decides what data to send back when call is made\n\n# Testing DOM Interaction and Routing Components\n * [heroes component](ngUnitTestingDemo\\src\\app\\heroes\\heroes.component.spec.ts)\n\n* jasmine.spyOn - look for fn on component and see if its watched\n* unfortanly routing test is flaky\n\n## Emitting events from children\n* hey you have an event just raise it\n* just test the boundaries\n\n## Interact with Input Boxes\n[hero detail compeont](ngUnitTestingDemo\\src\\app\\hero-detail\\hero-detail.component.spec.ts)\n\n## Tested with ActivatedRoute\n* your should not check the framework  works\n* asusme framework works correctly\n* formsmodule is not to difficult\n\n\n\n# Advanced topics\n\n## Adding Async code\n * debounce fn\n ```ts\n  debounce(func, wait, immediate) {\n    var timeout;\n    return function() {\n      var context = this, args = arguments;\n      var later = function() {\n        timeout = null;\n        if (!immediate) func.apply(context, args);\n      };\n      var callNow = immediate \u0026\u0026 !timeout;\n      clearTimeout(timeout);\n      timeout = setTimeout(later, wait);\n      if (callNow) func.apply(context, args);\n    };\n  }\n ```\n\n * use done paramater to let jasmine know its async\n\n\n ## Fake Async helper \n\n * fakeAsync \n * fast forward through time\n angular runs in zone, when you use fakeAsync you run in a different zone where you can control the passage of time with the tick fn\n * if we dont know how long use flush fn\n\n ## Wait for async\n\n * used with promises\n* __fixture.whenStable()__ - when all promises has resolved its a promise itself\n\n\n## Coverage Report\n* snapshot of current unit test state\n```\nnpx ng test --no-watch --code-coverage\n```\n* coverage/[project name]\n* on matteers is index.html\n* code coverage only knows about code that gets loaded\n* in production this a less of an issue","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwindmillcode%2Funit_testing_in_angular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwindmillcode%2Funit_testing_in_angular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwindmillcode%2Funit_testing_in_angular/lists"}