bahmutov / bahmutov/cypress-angular-unit-test

initEnv's & initEnvHtml's component parameter should be removed

Open
#248 2 comments 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
160
Forks
32
PR merge metrics
No merged PRs in 30d

Description

## Current Behavior

`initEnv`'s & `initEnvHtml`'s first parameter is a component that should be added to `TestBed`'s declarations.

In most cases, developers will import the module containing the component to avoid redeclaring all the imported dependencies like this:
```ts
initEnvHtml(undefined, {imports: [MyTestedModule]});
mount(MyTestedComponent);
```

instead of:

```ts
initEnv(MyTestedComponent, {imports: [AModule, BModule]});
mount(MyTestedComponent)
```

because in the latter case, developers will have to maintain the `imports` as the test is coupled to the implementation details.

In the rare cases where developers want to declare a component without importing modules, they can still use `TestModuleMetadata.declarations` like this:

```ts
initEnvHtml(undefined, {declarations: [MyTestedComponent]});
```

Using `declarations` is natural and least surprising for Angular developers.

## Issues with current behavior

1. Developers have to declare components|pipes|directives instead of importing the containing module.
2. Declaring a component and importing the containing module will produce a duplicate declaration error.
3. In order to just import the containing module, we have to call `initEnvHtml(undefined, {imports: ...})` which is not very intuitive nor convenient.

## Suggestions

Here are some suggestions that avoid introducing any breaking changes.

A. Deprecate `initEnv` and `initEnvHtml` and introduce a new function for initializing the environment that only takes `moduleDef` as a single parameter.

Ideas for naming the function are welcome! I am currently thinking of `initTestBed` or `configure` or `setUpEnv`.

```ts
initTestBed({declarations: [MyTestedComponent});
initTestBed({imports: [MyTestedModule]});
```

B. This one can be an addition to A.
In order to make things easier when developers only have one test in a test block, we can merge `mount` and `init` in one function by passing the `moduleDef`

B.1. ... as an additional parameter

```ts
mount(MyTestedComponent, {myInput: 'hello'}, {imports: [MyTestedModule]});
```

B.2. ... or a parameter also containing the inputs

```ts
mount(MyTestedComponent, {
imports: [MyTestedModule]
inputs: {myInput: 'hello'}
});
```

C. Keep things like they are and let Younes cry 😭

I'll be more than happy to contribute with a PR if we agree on the issue and a solution.

Contributor guide

No contributing guide indexed for this repository

Research direction

The issue identifies initEnv, initEnvHtml, TestBed metadata, and mount as relevant entry points. First locate their definitions and determine which proposed API the maintainers accept; the issue currently presents several alternatives without a decision. Done means the agreed initialization API avoids duplicate declarations and handles the existing usage appropriately.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, cypress, typescript
Domain
frontend, testing
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.