flutter Mock Service

Baek Dong Hyun·2023년 2월 23일
0

이번에 인강을 보면서 mock service를 사용하는 부분을 공부하게 되었다.
그러면서 이 기능을 내 개인 프로젝트에 적용해보면 어떨까 싶어서 사용해보았는데 그 부분을 정리해보려고 한다.

기존에 만들었었던 짱구 MBTI를 수정을 했다.

json 파일을 불러오거나 하는 방법을 몰랐었는데 이번 기회에 적용을 했다.
기존에 사용했던 mbti test용 데이터들을 하나하나 일일이 담아서 적용했는데 이번에 아얘 json 파일로 변경해 asset에 넣었다.

그 후 pubspec.yaml 파일에 asset을 추가한다.

모델 작업을 진행한다.

mbti 문제 데이터

import 'package:json_annotation/json_annotation.dart';

part 'question_model.g.dart';

()
class QuestionListModel {
  (
    name: 'list'
  )
  final List<Question> questionList;

  QuestionListModel({required this.questionList});

  factory QuestionListModel.fromJson(Map<String, dynamic> json) => _$QuestionListModelFromJson(json);
}

()
class Question {

  final String title;
  final String type;
  final String answerA;
  final String answerB;

  Question({
    required this.title,
    required this.type,
    required this.answerA,
    required this.answerB
  });

  factory Question.fromJson(Map<String, dynamic> json) => _$QuestionFromJson(json);
}

mbti 결과 데이터

import 'package:json_annotation/json_annotation.dart';

part 'result_model.g.dart';

()
class ResultListModel {
  final List<ResultDetail> resultList;

  ResultListModel({
    required this.resultList
  });

  factory ResultListModel.fromJson(Map<String, dynamic> json) => _$ResultListModelFromJson(json);
}

()
class ResultDetail {
  final String type;
  final ResultContent detail;

  ResultDetail({
    required this.type,
    required this.detail
  });

  factory ResultDetail.fromJson(Map<String, dynamic> json) => _$ResultDetailFromJson(json);
}

()
class ResultContent {
  final String name;
  final String contents;
  final String path;

  ResultContent({
    required this.name,
    required this.contents,
    required this.path
  });

  factory ResultContent.fromJson(Map<String, dynamic> json) => _$ResultContentFromJson(json);
}

위와같이 모델작업을 한 후 본격적으로 mock service 작업을 시작했다.

json data 들을 dart model 로 변경한 후에 데이터를 전달해줄거기 때문에 dart model 로 변경하는 시간이 조금 걸릴 수가 있다고 한다.

ex)

final jsonString = await rootBundle.loadString('assets/data.json');

이렇게하면 json 파일을 불러올 수 있다.
여기서 rootBundle을 사용하면 text assets을 로드 할 수 있다고 한다.

작성을 해보자면

import 'dart:convert';

import 'package:chopper/chopper.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/services.dart';
import 'package:zzang_gu_mbti/domain/models/models.dart';

class QuestionMockService {
  late final QuestionListModel _questionListModel;

  void loadQuestion() async {
    final jsonStr = await rootBundle.loadString('asset/data/test.json');
    final json = jsonDecode(jsonStr);
    _questionListModel = QuestionListModel.fromJson(json);
  }

  Future<Response<Result<QuestionListModel>>> queryQuestion() {
    return Future.value(
      Response(
        http.Response(
          'Dummy',
          200,
          request: null
        ),
        Success<QuestionListModel>(_questionListModel)
      )
    );
  }
}

하나씩 보자면

void loadQuestion() async {
  final jsonStr = await rootBundle.loadString('asset/data/test.json');
  final json = jsonDecode(jsonStr);
  _questionListModel = QuestionListModel.fromJson(json);
}

이렇게 작성해 json data를 불러오고 디코딩해준 후 맵핑한다.
그 후 서비스 코드를 작성하면

Future<Response<Result<QuestionListModel>>> queryQuestion() {
  return Future.value(
    Response(
      // 여긴 base
      http.Response(
        'Dummy', // body
        200, // status code
        request: null, // 안써서 null 로 한다고 함
      ), // 중요한건 이 Response 부분이 아니라
      // 여긴 body
      Success<QuestionListModel>(_questionListModel)  // 이 body 부분이 중요하다고 함
    )
  );
 }

이렇게 작성 할 수 있다.
그리고 이 mock service로 작성한 코드를 Provider에 담아서 사용할 것이기 때문에 main.dart에서

Widget build(BuildContext context) {
  return MultiProvider(
    providers: [
      Provider(create: (_) => QuestionMockService()..loadQuestion(), lazy: false,),
      Provider(create: (_) => ResultMockService()..loadResult(), lazy: false,)
    ],
    child: MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        fontFamily: 'sunflower'
      ),
      home: const HomeScreen(),
    ),
  );
}

이렇게 작성해서 넣어주었다.
이제 불러와서 사용할 때는

FutureBuilder<Response<Result<QuestionListModel>>>(
  future: Provider.of<QuestionMockService>(context).queryQuestion(),
  builder: (context, snapshot) {
    return ;
  }
),

이런식으로 타입을 작성해주고 사용하면 됐다.

profile
안녕하세요.

0개의 댓글