{"id":6927,"date":"2023-01-26T02:19:55","date_gmt":"2023-01-26T01:19:55","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=6927"},"modified":"2023-09-04T12:58:09","modified_gmt":"2023-09-04T10:58:09","slug":"testing-angular-standalone-components","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/","title":{"rendered":"Testing Angular Standalone Components"},"content":{"rendered":"<div class=\"wp-post-series-box series-angulars-future-without-ngmodules wp-post-series-box--expandable\">\n\t\t\t<input id=\"collapsible-series-angulars-future-without-ngmodules69e5c9cf3df18\" class=\"wp-post-series-box__toggle_checkbox\" type=\"checkbox\">\n\t\n\t<label\n\t\tclass=\"wp-post-series-box__label\"\n\t\t\t\t\tfor=\"collapsible-series-angulars-future-without-ngmodules69e5c9cf3df18\"\n\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\t\t<p class=\"wp-post-series-box__name wp-post-series-name\">\n\t\t\tThis is post 7 of 8 in the series <em>&ldquo;Angular&#039;s Future with Standalone Components&rdquo;<\/em>\t\t<\/p>\n\t\t\t<\/label>\n\n\t\t\t<div class=\"wp-post-series-box__posts\">\n\t\t\t<ol>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/angulars-future-without-ngmodules-lightweight-solutions-on-top-of-standalone-components\/\">Angular&#8217;s Future Without NgModules &#8211; Part 1: Lightweight Solutions Using Standalone Components<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/angulars-future-without-ngmodules-part-2-what-does-that-mean-for-our-architecture\/\">Angular&#8217;s Future Without NgModules &#8211; Part 2: What Does That Mean for Our Architecture?<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/4-ways-to-prepare-for-angulars-upcoming-standalone-components\/\">4 Ways to Prepare for Angular&#8217;s Upcoming Standalone Components<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/routing-and-lazy-loading-with-standalone-components\/\">Routing and Lazy Loading with Angular&#8217;s Standalone Components<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-web-components-with-standalone-components\/\">Angular Elements: Web Components with Standalone Components<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/the-refurbished-httpclient-in-angular-15-standalone-apis-and-functional-interceptors\/\">The Refurbished HttpClient in Angular 15 &#8211; Standalone APIs and Functional Interceptors<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><span class=\"wp-post-series-box__current\">Testing Angular Standalone Components<\/span><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/tutorial-automatically-migrating-to-standalone-components-in-3-steps\/\">Automatic Migration to Standalone Components in 3 Steps<\/a><\/li>\n\t\t\t\t\t\t\t<\/ol>\n\t\t<\/div>\n\t<\/div>\n<p>With Standalone Components, Angular becomes a lot more lightweight: NgModules are optional and hence we can work with lesser indirections. To make this possible, components now refer directly to their dependencies: other components, but also directives and pipes. There are so-called Standalone APIs for configuring services such as the <code>HttpClient<\/code>.<\/p>\n<p>Additional Standalone APIs provide mocks for test automation. Here, I'm going to present these APIs. For this, I focus on on-board tools supplied with Angular. The \ud83d\udcc2 <a href=\"https:\/\/github.com\/manfredsteyer\/standalone-example-cli.git\">examples<\/a> used can be found <a href=\"https:\/\/github.com\/manfredsteyer\/standalone-example-cli.git\">here<\/a><\/p>\n<p>If you don't want to be go with the on-board resources alone, you will find the same examples based on the new Cypress Component Test Runner and on Testing Library in the <code>third-party-testing<\/code> branch.<\/p>\n<blockquote>\n<p>Big thanks to my colleague and Angular testing expert <a href=\"https:\/\/twitter.com\/rainerhahnekamp\">Rainer Hahnekamp<\/a> who reviewed this article and also provided the mentioned examples using Cypress and the Testing Library.<\/p>\n<\/blockquote>\n<h2>Test Setup<\/h2>\n<p>Even though Standalone Components make modules optional, the <code>TestBed<\/code> still comes with a testing module. It takes care of the test setup and provides all components, directives, pipes, and services for the test:<\/p>\n<pre><code class=\"language-typescript\">import { provideHttpClient } from &#039;@angular\/common\/http&#039;;\nimport { HttpTestingController, provideHttpClientTesting } \n    from &#039;@angular\/common\/http\/testing&#039;;\n\n[\u2026]\n\ndescribe(&#039;FlightSearchComponent&#039;, () =&gt; {\n  let component: FlightSearchComponent;\n  let fixture: ComponentFixture&lt;FlightSearchComponent&gt;;\n  beforeEach(async () =&gt; {\n\n    await TestBed.configureTestingModule({\n      imports: [ FlightSearchComponent ],\n      providers: [\n        provideHttpClient(),\n        provideHttpClientTesting(),\n\n        provideRouter([]),\n\n        provideStore(),\n        provideState(bookingFeature),\n        provideEffects(BookingEffects),\n      ],\n    })\n    .compileComponents();\n\n    fixture = TestBed.createComponent(FlightSearchComponent);\n    component = fixture.componentInstance;\n    fixture.detectChanges();\n  });\n\n  it(&#039;should search for flights&#039;, () =&gt; { [\u2026] });\n});<\/code><\/pre>\n<p>The example shown imports the Standalone Component to be tested and provides the required services via the <code>providers<\/code> array. This is exactly where the mentioned Standalone APIs come into play. They provide the services for the <code>HttpClient<\/code>, the router and NGRX.<\/p>\n<p>The <code>provideStore<\/code> function sets up the NGRX store, <code>provideState<\/code> provides a feature slice required for the test and <code>provideEffects<\/code> registers an associated effect. Below we will swap out these constructs for mocks.<\/p>\n<p>The <code>provideHttpClientTesting<\/code> method is interesting: it overrides the <code>HttpBackend<\/code> used behind the scenes by the <code>HttpClient<\/code> with an <code>HttpTestingBackend<\/code> that simulates HTTP calls. It should be noted that it must be called after (!) <code>provideHttpClient<\/code>.<\/p>\n<p>It is therefore first necessary to set up the <code>HttpClient<\/code> by default in order to then overwrite individual details for testing. This is a pattern we will see again below when testing the router.<\/p>\n<h2>The HttpClient Mock<\/h2>\n<p>Once the <code>HttpClient<\/code> and <code>HttpTestingBackend<\/code> have been set up, the individual tests are implemented as usual: The test uses the <code>HttpTestingController<\/code> to find out about pending HTTP requests and to specify the HTTP responses to be simulated:<\/p>\n<pre><code class=\"language-typescript\">it(&#039;should search for flights&#039;, () =&gt; {\n  component.from = &#039;Paris&#039;;\n  component.to = &#039;London&#039;;\n  component.search();\n\n  const ctrl = TestBed.inject(HttpTestingController);\n\n  const req = ctrl.expectOne(&#039;https:\/\/[\u2026]\/flight?from=Paris&amp;to=London&#039;);\n  req.flush([{}, {}, {}]); \/\/ return 3 empty objects as dummy flights\n\n  component.flights$.subscribe(flights =&gt; {\n    expect(flights.length).toBe(3);\n  });\n\n  ctrl.verify();\n});<\/code><\/pre>\n<p>The test then checks whether the component processed the simulated HTTP response as intended. In the case shown, the test assumes that the component offers the received flights via its <code>flights<\/code> property.<\/p>\n<p>At the end, the test ensures that there are no further HTTP requests that have not yet been answered. To do this, it calls the <code>verify<\/code> method provided by the <code>HttpTestingController<\/code>. If there are still open requests at this point, <code>verify<\/code> throws an exception that causes the test to fail.<\/p>\n<h2>Shallow Testing<\/h2>\n<p>If you test a component, all sub-components, directives, and pipes used in the template are automatically tested as well. This is undesirable, especially for unit tests that focus on a single code unit. Also, this behavior slows down test execution when there are many dependencies.<\/p>\n<p>Shallow tests are used to prevent this. This means that the test setup replaces all dependencies with mocks. These mocks must have the same interface as the replaced dependencies. In the case of components, this means -- among other things -- that the same properties and events (inputs and outputs) must be offered, but also that the same selectors must be used.<\/p>\n<p>The <code>TestBed<\/code> offers the <code>overrideComponent<\/code> method for exchanging these dependencies:<\/p>\n<pre><code class=\"language-typescript\">await TestBed.configureTestingModule([\u2026])\n  .overrideComponent(FlightSearchComponent, {\n    remove: { imports: [ FlightCardComponent ] },\n    add: { imports: [ FlightCardMock ] }\n  })\n  .compileComponents();<\/code><\/pre>\n<p>In the case shown, the <code>FlightSearchComponent<\/code> uses another Standalone Component in its template: the <code>FlightCardComponent<\/code>. Technically, this means that the <code>FlightCardComponent<\/code> appears in the <code>imports<\/code> array of <code>FlightSearchComponent<\/code>. For implementing a shallow Test, this entry is removed. As a replacement, the <code>FlightCardMock<\/code> is added. The <code>remove<\/code> and <code>add<\/code> methods take care of this task.<\/p>\n<p>The <code>FlightSearchComponent<\/code> is thus used in the test without real dependencies. Nevertheless, the test can check whether components behave as desired. For example, the following listing checks whether the <code>FlightSearchComponent<\/code> sets up an element named <code>flight-card<\/code> for each flight found.<\/p>\n<pre><code class=\"language-typescript\">it(&#039;should display a flight-card for each found flight&#039;, () =&gt; {\n  component.from = &#039;Paris&#039;;\n  component.to = &#039;London&#039;;\n  component.search();\n\n  const ctrl = TestBed.inject(HttpTestingController);\n\n  const req = ctrl.expectOne(&#039;https:\/\/[\u2026]\/flight?from=Paris&amp;to=London&#039;);\n  req.flush([{}, {}, {}]);\n\n  fixture.detectChanges();\n\n  const cards = fixture.debugElement.queryAll(By.css(&#039;flight-card&#039;));\n  expect(cards.length).toBe(3);\n});<\/code><\/pre>\n<h3>More: Professional Angular Testing Workshop (online, interactive, advanced)<\/h3>\n<p>Improve your software quality and make your live easier with our <a href=\"https:\/\/www.angulararchitects.io\/en\/angular-workshops\/professional-angular-testing-workshop\/\">Professional Angular Testing Workshop!<\/a><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2018\/02\/testing-en-twitter.png\" alt=\"\" \/><a href=\"https:\/\/www.angulararchitects.io\/en\/angular-workshops\/professional-angular-testing-workshop\/\">All Details (English Workshop)<\/a> | <a href=\"https:\/\/www.angulararchitects.io\/schulungen\/professional-angular-testing\/\">All Details (German Workshop)<\/a><br \/>\n<\/p>\n<h2>Mock Router and Store<\/h2>\n<p>The test setup used so far only simulated the <code>HttpCient<\/code>. However, there are also Standalone APIs for mocking the router and NGRX:<\/p>\n<pre><code class=\"language-typescript\">import { provideRouter } from &#039;@angular\/router&#039;;\nimport { provideLocationMocks } from &#039;@angular\/common\/testing&#039;;\n\nimport { provideMockStore } from &#039;@ngrx\/store\/testing&#039;;\nimport { provideMockActions } from &#039;@ngrx\/effects\/testing&#039;;\n\n[\u2026]\n\ndescribe(&#039;FlightSearchComponent (at router level)&#039;, () =&gt; {\n  let component: FlightSearchComponent;\n  let fixture: ComponentFixture&lt;FlightSearchComponent&gt;;\n  let actions$ = new Subject&lt;Action&gt;();\n\n  beforeEach(async () =&gt; {\n    await TestBed.configureTestingModule({\n      providers: [\n        provideHttpClient(),\n        provideHttpClientTesting(),\n\n        provideRouter([\n          { path: &#039;flight-edit\/:id&#039;, component: FlightEditComponent }\n        ]),\n        provideLocationMocks(),\n\n        provideMockStore({\n          initialState: {\n            [BOOKING_FEATURE_KEY]: {\n              flights: [{ id:1 }, { id:2 }, { id:3 }],\n            },\n          },\n        }),\n\n        provideMockActions(() =&gt; actions$),\n      ],\n      imports: [FlightSearchComponent],\n    }).compileComponents();\n\n    fixture = TestBed.createComponent(FlightSearchComponent);\n    component = fixture.componentInstance;\n    fixture.detectChanges();\n  });\n\n  [\u2026]\n});<\/code><\/pre>\n<p>As with testing the <code>HttpClient<\/code>, the test first sets up the router in the usual way. Then, it uses <code>provideLocationMocks<\/code> to override a couple of internally used services, namely <code>Location<\/code> and <code>LocationStrategy<\/code>. This procedure allows the route change to be simulated in the test cases. The <code>MockStore<\/code> which also ships with NGRX is used instead of the traditional one. It allows the entire content of the store to be freely defined. This is done either by calling <code>provideMockStore<\/code> or via its <code>setState<\/code> method. Also, <code>provideMockActions<\/code> gives us the ability to swap out the <code>actions$<\/code> observable that NGRX effects often rely on. A test case using this setup could look like as follows: <\/p>\n<pre><code class=\"language-typescript\">it(&#039;routes to flight-card&#039;, fakeAsync(() =&gt; {\n\n  const link = fixture.debugElement.query(By.css(&#039;a[class*=btn-default ]&#039;))\n  link.nativeElement.click();\n\n  flush();\n  fixture.detectChanges();\n\n  const location = TestBed.inject(Location);\n  expect(location.path()).toBe(&#039;\/flight-edit\/1;showDetails=false&#039;)\n\n}));<\/code><\/pre>\n<p>This test assumes that the <code>FlightSearchComponent<\/code> displays one link per flight in the (mock)store. It simulates a click on the first link and checks whether the application then switches to the expected route. In order for Angular to process the simulated click and trigger the route change, the change detection must be running. Unfortunately, this is not automatically the case with tests. Instead, it is to be triggered with the <code>detectChanges<\/code> method when required. The operations involved are asynchronous. Hence, <code>fakeAsync<\/code> is used so that the we don't need to burdened ourselves with this. It allows pending micro-tasks to be processed synchronously using <code>flush.<\/code>## Testing Effects<\/p>\n<p>The <code>MockStore<\/code> does not trigger reducers or effects. The former are just functions and can be tested in a straight forward way. Replacing <code>action$<\/code> is a good way to test effects. The test setup in the last section has already taken care of that. A test based on this could now use the observable <code>action$<\/code> to send an action to which the tested effect reacts: <\/p>\n<pre><code class=\"language-typescript\">it(&#039;load flights&#039;, () =&gt; {\n  const effects = TestBed.inject(BookingEffects);\n  let flights: Flight[] = [];\n\n  effects.loadFlights$.subscribe(action =&gt; {\n    flights = action.flights; \/\/ Action returned from Effect\n  });\n\n  actions$.next(loadFlights({ from: &#039;Paris&#039;, to: &#039;London&#039; }));\n    \/\/ Action sent to store to invoke Effect\n\n  const ctrl = TestBed.inject(HttpTestingController);\n  const req = ctrl.expectOne(&#039;https:\/\/[\u2026]\/flight?from=Paris&amp;to=London&#039;);\n  req.flush([{}, {}, {}]);\n\n  expect(flights.length).toBe(3);\n});<\/code><\/pre>\n<p>In the case under consideration, the effect triggers an HTTP call answered by the <code>HttpTestingController<\/code>. The response contains three flights, represented by three empty objects for the sake of simplicity. Finally, the test checks whether the effect provided these flights via the outbound action. ## Summary<\/p>\n<p>More and more libraries offer Standalone APIs for mocking dependencies. These either provide a mock implementation or at least overwrite services in the actual implementation to increase testability. The <code>TestingModule<\/code> is still used to provide the test setup. Unlike before, however, it now imports the standalone components, directives, and pipes to be tested. Their classic counterparts, on the other hand, were declared. In addition, the <code>TestingModule<\/code> now includes providers setup by Standalone APIs. ## More on Standalone Components?<\/p>\n<p>Learn all about Standalone Components in our free eBook: - The mental model behind Standalone Components<\/p>\n<ul>\n<li>Migration scenarios and compatibility with existing code<\/li>\n<li>Standalone Components and the router and lazy loading<\/li>\n<li>Standalone Components and Web Components<\/li>\n<li>Standalone Components and DI and NGRX<\/li>\n<\/ul>\n<p>Please find our eBook here: <a href=\"https:\/\/www.angulararchitects.io\/standalone-book\"><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/10\/title-page-small.jpg\" alt=\"free\" \/><\/a>Feel free to <a href=\"https:\/\/www.angulararchitects.io\/standalone-book\">download it here<\/a> now!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>New Standalone APIs provide mocks for test automation.<\/p>\n","protected":false},"author":9,"featured_media":6928,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-6927","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","post_series-angulars-future-without-ngmodules"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Testing Angular Standalone Components - ANGULARarchitects<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Testing Angular Standalone Components - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"New Standalone APIs provide mocks for test automation.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2023-01-26T01:19:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-04T10:58:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/sm-2.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"500\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manfred Steyer, GDE\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/sm-2.jpg\" \/>\n<meta name=\"twitter:creator\" content=\"@daniel\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer, GDE\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/\"},\"author\":{\"name\":\"Manfred Steyer, GDE\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\"},\"headline\":\"Testing Angular Standalone Components\",\"datePublished\":\"2023-01-26T01:19:55+00:00\",\"dateModified\":\"2023-09-04T10:58:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/\"},\"wordCount\":1124,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/shutterstock-1832152525.jpg\",\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/\",\"name\":\"Testing Angular Standalone Components - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/shutterstock-1832152525.jpg\",\"datePublished\":\"2023-01-26T01:19:55+00:00\",\"dateModified\":\"2023-09-04T10:58:09+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/shutterstock-1832152525.jpg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/shutterstock-1832152525.jpg\",\"width\":1000,\"height\":667},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Testing Angular Standalone Components\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\",\"name\":\"Manfred Steyer, GDE\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer, GDE\"},\"sameAs\":[\"https:\/\/x.com\/daniel\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Testing Angular Standalone Components - ANGULARarchitects","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/","og_locale":"en_US","og_type":"article","og_title":"Testing Angular Standalone Components - ANGULARarchitects","og_description":"New Standalone APIs provide mocks for test automation.","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/","og_site_name":"ANGULARarchitects","article_published_time":"2023-01-26T01:19:55+00:00","article_modified_time":"2023-09-04T10:58:09+00:00","og_image":[{"width":1000,"height":500,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/sm-2.jpg","type":"image\/jpeg"}],"author":"Manfred Steyer, GDE","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/sm-2.jpg","twitter_creator":"@daniel","twitter_misc":{"Written by":"Manfred Steyer, GDE","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/"},"author":{"name":"Manfred Steyer, GDE","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951"},"headline":"Testing Angular Standalone Components","datePublished":"2023-01-26T01:19:55+00:00","dateModified":"2023-09-04T10:58:09+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/"},"wordCount":1124,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/shutterstock-1832152525.jpg","inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/","name":"Testing Angular Standalone Components - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/shutterstock-1832152525.jpg","datePublished":"2023-01-26T01:19:55+00:00","dateModified":"2023-09-04T10:58:09+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/shutterstock-1832152525.jpg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/01\/shutterstock-1832152525.jpg","width":1000,"height":667},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/testing-angular-standalone-components\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"Testing Angular Standalone Components"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951","name":"Manfred Steyer, GDE","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","caption":"Manfred Steyer, GDE"},"sameAs":["https:\/\/x.com\/daniel"]}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/6927","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=6927"}],"version-history":[{"count":1,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/6927\/revisions"}],"predecessor-version":[{"id":22324,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/6927\/revisions\/22324"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/6928"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=6927"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=6927"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=6927"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}