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

[Part 5] Running the test fails with null safety enabled #5

Open
flutternoob opened this issue May 20, 2021 · 1 comment
Open

[Part 5] Running the test fails with null safety enabled #5

flutternoob opened this issue May 20, 2021 · 1 comment

Comments

@flutternoob
Copy link

I am trying to run the code with null safety enabled in the project. I keep getting the following error when I run the test on counter_cubit_test.dart:

Null check operator used on a null value

This is the code in the counter_cubit.dart file:

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';

part 'counter_state.dart';

class CounterCubit extends Cubit<CounterState> {
  CounterCubit() : super(CounterState(counterValue: 0));

  void increment() => emit(
      CounterState(counterValue: state.counterValue! + 1, wasIncremented: true));

  void decrement() => emit(CounterState(
      counterValue: state.counterValue! - 1, wasIncremented: false));
}

This is the code in the counter_state.dart file:

part of 'counter_cubit.dart';

class CounterState extends Equatable {
  final int? counterValue;
  final bool? wasIncremented;

  CounterState({required this.counterValue, this.wasIncremented});

  @override
  List<Object> get props => [this.counterValue!, this.wasIncremented!];
}

This is the code in the main.dart file:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_counter_bloc/cubits/counter_cubit.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter Demo",
      theme: ThemeData(
        primaryColor: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: BlocProvider<CounterCubit>(
        create: (context) => CounterCubit(),
        child: MyHomePage(title: "Flutter Demo Home Page"),
      ),
    );
  }
}

///Used a stateless widget since state is handled by the Bloc library in this case. I referred the
///following link: https://stackoverflow.com/questions/58864869/flutter-state-management-bloc-stateless-vs-stateful-widget
class MyHomePage extends StatelessWidget {
  final String? title;

  const MyHomePage({Key? key, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title!),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text("You have pushed this button this many times:"),
            BlocConsumer<CounterCubit, CounterState>(
              ///Refactored the if...else block into a function to show the SnackBar Widget
                listener: (context, state) => snackBarFunction(state.wasIncremented!, context),
                ///Refactored the if...else block into a function that returns a Text widget
                builder: (context, state) => counterText(state.counterValue!, context)),
            SizedBox(height: 24),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                FloatingActionButton(
                  onPressed: () => BlocProvider.of<CounterCubit>(context).decrement(),
                  heroTag: Text("$title"),
                  tooltip: "Decrement",
                  child: Icon(Icons.remove),
                ),
                FloatingActionButton(
                  onPressed: () => BlocProvider.of<CounterCubit>(context).increment(),
                  heroTag: Text("$title #2"),
                  tooltip: "Increment",
                  child: Icon(Icons.add),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }
}

///This function is used to show the snack bar widget depending on whether the counter was incremented
///or decremented
void snackBarFunction(bool counterState, context) {
  if (counterState == true) {
    ///Scaffold.of(context).showSnackBar(snackBar) is deprecated
    ///Using ScaffoldMessenger.of(context).showSnackBar(snackBar) instead
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      content: Text("Incremented!"),
      duration: Duration(milliseconds: 300),
    ));
  } else {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      content: Text("Decremented!"),
      duration: Duration(milliseconds: 300),
    ));
  }
}

///This function is used to change the returned Text widget in accordance with the value of the counter
Text counterText(int counterValue, context) {
  if (counterValue < 0) {
    return Text("BRR, Negative $counterValue",
        style: Theme.of(context).textTheme.headline4);
  } else if (counterValue % 2 == 0) {
    return Text("YAAAY $counterValue",
        style: Theme.of(context).textTheme.headline4);
  } else if (counterValue == 5) {
    return Text("HMM, NUMBER 5", style: Theme.of(context).textTheme.headline4);
  } else {
    return Text("$counterValue",
        style: Theme.of(context).textTheme.headline4);
  }
}

This is the code in the counter_cubit_test.dart file:

import 'package:flutter_counter_bloc/cubits/counter_cubit.dart';
import 'package:test/test.dart';
import 'package:bloc_test/bloc_test.dart';

void main() {
  group("CounterCubit", (){

    CounterCubit? counterCubit;

    setUp((){
      counterCubit = CounterCubit();
    });
    tearDown((){
      counterCubit!.close();
    });

    test("Initial state of CounterCubit is CounterState(counterValue: 0)", () {
      expect(counterCubit!.state, CounterState(counterValue: 0));
    });

    blocTest<CounterCubit, CounterState>(
      'the CounterCubit should emit a CounterState(counterValue:1, wasIncremented:true) when the increment function is called',
      build: () => counterCubit!,
      act: (cubit) => cubit.increment(),
      expect: () => <CounterState>[CounterState(counterValue: 1, wasIncremented: true)],
    );

    blocTest<CounterCubit, CounterState>(
      'the CounterCubit should emit a CounterState(counterValue:-1, wasIncremented:false) when the decrement function is called',
      build: () => counterCubit!,
      act: (cubit) => cubit.decrement(),
      expect: () => <CounterState>[CounterState(counterValue: -1, wasIncremented: false)],
    );
  });
}
@wxluoweihao
Copy link

wxluoweihao commented Aug 12, 2021

It seems to me that you specified the program may expect null reference object on type CounterCubit. Change "CounterCubit? counterCubit" to "late CounterCubit counterCubit", and replace any "counterCubit!" occurrences to "counterCubit" should work.

https://medium.com/flutterworld/flutter-null-safety-5d20012c2441

group('CounterCubit', () {
    late CounterCubit counterCubit;

    setUp((){
      counterCubit = CounterCubit();
    });

    tearDown((){
      counterCubit.close();
    });

    test('the initial state for the CounterCubit is CounterState(counterValue:0)', () {
      expect(counterCubit.state, CounterState(counterValue: 0, wasIncremented: false));
    });

    blocTest('the cubit should emit a CounterState(counterValue: 1, wasIncremented:true) when cubit.increment() function is called',
      build: () => counterCubit,
      act: (cubit) => counterCubit.increment(),
      expect: () => [CounterState(counterValue: 1, wasIncremented: true)],
    );

    blocTest('the cubit should emit a CounterState(counterValue: -1, wasIncremented:false) when cubit.decrement() function is called',
      build: () => counterCubit,
      act: (cubit) => counterCubit.decrement(),
      expect: () => [CounterState(counterValue: -1, wasIncremented: false)],
    );
  });

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

2 participants