Bloc: [question] `setup()` is not called before `expect` is evaluated

Created on 6 Jun 2020  路  3Comments  路  Source: felangel/bloc

Describe the bug
When calling blocTest(), I'm getting a NullPointerException error when I access a field inside expect even though that field was previously initialized in a setUp() call.

When I traced using breakpoints, the expect block was indeed executed before the setUp() call. I'm a newb to Dart, so I didn't dive in to the source code yet 馃槂

To Reproduce
Sample test:

group("NPE test group", () {
    int origLength;
    setUp(() {
      origLength = 1; // dummy value
    });

    blocTest(
      "NPE test",
      build: () async => MyBloc(),
      expect: [...List.filled(origLength, 0)], // this throws NPE
    );
});

Expected behavior
I expected that setUp() would be called first before the expect block is executed.

Logs

Invalid argument (length): is not an integer: null
dart:core                                                                                                                          new List.filled

Additional context
I checked that #993 seems like a related issue. It was suggested to do some initialization in build instead. But I want to use this field in other tests as well, and I couldn't find this documented anywhere too.

bloc: ^4.0.0
bloc_test: ^5.1.0

Thanks!

bloc_test question wontfix

Most helpful comment

Thanks again for looking into this. If the fix breaks the API, then no need to fix this.

I just thought it would be like JUnit where @Before setUp() is always called before any @Test. Or should I have wrote the setup outside the group() in this case?

It's a sneaky gotcha for newbies 馃槵. I got stuck for half an hour looking for something wrong in the code , kept wondering why the verify works but not the expect.

Thanks again. We can close this ticket.

All 3 comments

Hi @greenlover1991 馃憢
Thanks for opening an issue!

I鈥檒l have a look ASAP 馃憤

Hey @greenlover1991 I took a look and the issue is, the expect does in fact get evaluated before setUp. The only way I can think of to fix this is to break the blocTest api to have expect be a method that returns the iterable of matchers.

blocTest(
  "NPE test",
  build: () async => MyBloc(),
  expect: () => [...List.filled(origLength, 0)], // this throws NPE
);

I'd prefer not to make this change; however, because I believe you should not be using dynamic variables in the expectation of your bloc test and should instead either make it a final or even constant that is reused across multiple tests or have each test explicitly define it's own expect inline if they differ.

group("NPE test group", () {
    const origLength = 1;

    blocTest(
      "NPE test",
      build: () async => MyBloc(),
      expect: [...List.filled(origLength, 0)],
    );
});

Let me know what you think 馃憤

Thanks again for looking into this. If the fix breaks the API, then no need to fix this.

I just thought it would be like JUnit where @Before setUp() is always called before any @Test. Or should I have wrote the setup outside the group() in this case?

It's a sneaky gotcha for newbies 馃槵. I got stuck for half an hour looking for something wrong in the code , kept wondering why the verify works but not the expect.

Thanks again. We can close this ticket.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shawnchan2014 picture shawnchan2014  路  3Comments

komapeb picture komapeb  路  3Comments

RobPFarley picture RobPFarley  路  3Comments

rsnider19 picture rsnider19  路  3Comments

ricktotec picture ricktotec  路  3Comments