Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reactive form testing won't validate the form correctly #48

Closed
yackinn opened this issue Sep 17, 2020 · 12 comments
Closed

Reactive form testing won't validate the form correctly #48

yackinn opened this issue Sep 17, 2020 · 12 comments

Comments

@yackinn
Copy link

yackinn commented Sep 17, 2020

I'm submitting a...


[x] Bug report 

Current behavior

When testing a simple component that has a setup form method on init the test for an invalid form fails. The form is valid without having values.
Swapping the ngneat form builder for the Agnualr form builder from angular core it works fine.
The test will output the form's invalid property as true.

Logging the output in the browser works as expected.

Jest is used as a test runner

Expected behavior

The test should output an invalid form after setup.

Minimal reproduction of the problem with instructions

// component
@Component({
  selector: 'user-login',
  changeDetection: ChangeDetectionStrategy.OnPush,
  styleUrls: ['./login.component.scss'],
  templateUrl: './login.component.html'
})
export class LoginComponent implements OnInit {
  form;

... 

  constructor(
    private fb: FormBuilder,
  ) {}
  
  ngOnInit(): void {
    this.form = this.createForm();
    // console.log("component", this.form.valid)
    // console.log(this.form)
  }
  
  private createForm() {
    return this.fb.group({
      username: ['', Validators.required],
      password: ['', [Validators.required, Validators.minLength(10)]]
    });
  }
}

// test
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder, FormGroup } from '@ngneat/reactive-forms';

...
beforeEach(waitForAsync(() => {
   ...

    TestBed.configureTestingModule({
      declarations: [LoginComponent],
      imports: [
        ReactiveFormsModule
      ],
      providers: [
        FormBuilder,
        { provide: UserFacade, useValue: userFacade }
      ]
    }).compileComponents();
  }));
  
  beforeEach(async () => {
    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
  });

...
  
  describe('form invalid', () => {
      it('should NOT call userFacade.login', () => {
        component.ngOnInit();
        console.log(component.form.valid)     // ouput is true
      });
...

Environment


Angular version: 10.1.0
ng neat reactive forms version: 1.3.1

Browser:
- [x] Chrome (desktop) version 85.0.4183.102
- [x] Firefox (desktop) version 80.0.1

 
For Tooling issues:
- Node version: 12.18.3
- Platform: Macos

@NetanelBasal
Copy link
Member

@danzrou

@rafaelss95
Copy link
Contributor

rafaelss95 commented Nov 3, 2020

Just faced the same issue today after debugging it for an hour...

I noticed that (in tests) .errors/.validator returns undefined.

@NetanelBasal @danzrou do you have any idea from where should I look at to propose a fix? Or do you guys plan to fix it by yourself?

@NetanelBasal
Copy link
Member

@yackinn, can you create a reproduction on stackblitz, please?

@danzrou
Copy link
Collaborator

danzrou commented Nov 3, 2020

@rafaelss95 @yackinn - did you test it on latest version?
Basically, the group just generates form controls without any exceptions.
And a reproduction can be very useful, thanks

@rafaelss95
Copy link
Contributor

rafaelss95 commented Nov 3, 2020

@NetanelBasal @danzrou I've setup a NX project with Jest to demonstrate the issue here: https://github.com/rafaelss95/reactive-forms-48.

You can see that the tests will fail when you import FormBuilder from @ngneat/reactive-forms�, but that not happens when importing from @angular/forms. See this line:

https://github.com/rafaelss95/reactive-forms-48/blob/e3dec27190883d6ce245c2abe05497f9d697f43b/apps/reactive/src/app/app.component.ts#L3-L4

PS: If you put a console.log you'll see that both .errors and .validator return undefined.

@danzrou
Copy link
Collaborator

danzrou commented Nov 3, 2020

I honestly don't know what we're missing here.
This is a test I added:

it('should be invalid', () => {
    const group = fb.group<{password: string; username: string}>({
      password: ['', [Validators.required, Validators.minLength(10)]],
      username: ['', Validators.required]
    });

    expect(group.invalid).toBe(true);
  });

No errors.
Logging group's errors return null (because the error is on the control, not the group) and validators property doesn't exist on groups so its legit that it return undefined for you.

@rafaelss95
Copy link
Contributor

rafaelss95 commented Nov 3, 2020

I honestly don't know what we're missing here.
This is a test I added:

it('should be invalid', () => {
    const group = fb.group<{password: string; username: string}>({
      password: ['', [Validators.required, Validators.minLength(10)]],
      username: ['', Validators.required]
    });

    expect(group.invalid).toBe(true);
  });

Have you tested it using the repo I provided above? I literally copied your example and it doesn't seem to work there either.


Logging group's errors return null (because the error is on the control, not the group) and validators property doesn't exist on groups so its legit that it return undefined for you.

I mentioned .errors/.validator in the FormControl instance. As an example, you could add these tests:

expect(formGroup.get('password').errors).toEqual({ required: true });
expect(formGroup.get('username').errors).toEqual({ required: true });
expect(formGroup.get('password').validator).toBeDefined();
expect(formGroup.get('username').validator).toBeDefined();

All of them fail. It only works if you use FormBuilder from @angular/forms.

PS: I don't know if that matters, but in the repo I provided, I use Jest, not karma.

@danzrou
Copy link
Collaborator

danzrou commented Nov 3, 2020

Well, we're testing with Jest as well - this is the test I just ran and it passed with no errors :(

  it('should be invalid', () => {
    const group = fb.group<{password: string; username: string}>({
      password: ['', [Validators.required, Validators.minLength(10)]],
      username: ['', Validators.required]
    });


    expect(group.invalid).toBe(true);
    expect(group.get('password').errors).toEqual({ required: true });
    expect(group.get('username').errors).toEqual({ required: true });
    expect(group.get('password').validator).toBeDefined();
    expect(group.get('username').validator).toBeDefined();
  });

image

The difference that I am testing without any component, but that should not interfere in any way.
I'll fork your repo tomorrow to see what's going on

@rafaelss95
Copy link
Contributor

Well, we're testing with Jest as well - this is the test I just ran and it passed with no errors :(\

That's really strange 🤔.

I'll fork your repo tomorrow to check what's going on

Thanks 🙏.

@rafaelss95
Copy link
Contributor

Hey @danzrou, did you have any time to check it out? Please, let me know of any news.

@danzrou
Copy link
Collaborator

danzrou commented Nov 10, 2020

Hey, I actually did.
I tested in clean angular project as same as an nx one, and in ours.
As it only occurred in the nx project and specifically in tests (there are no errors in runtime) I assume this has to do either with jest configuration / jest-angular-preset / something else related to TS.
Currently closing this as its not the lib's issue

@danzrou danzrou closed this as completed Nov 10, 2020
@gabrielguerrero
Copy link

Hey guys, we are facing this same issue, we have a nx repo with jest where we been using ngneat/[email protected] for some time, and yesterday we tried to migrate to 1.7.0 and notice a bunch of test failing, I copied and pasted the simple test @rafaelss95 posted and they fail the same way, and manual testing of the app running showed the validation behaving fine so is only the test, we did discover something we downgraded versions to see with on which one the test pass and the did with 1.3.0, 1.3.1 makes them fail again, this is happening with @nrwl/[email protected] and [email protected] and ts 4.1.2, jest 26.2.2, I went through the commits between 1.3.0 and 1.3.1, and did not notice anything that could have caused this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants