【问题标题】:How to extract Left or Right easily from Either type in Dart (Dartz)如何从 Dart 中的任何一种类型中轻松提取左或右 (Dartz)
【发布时间】:2020-03-03 04:00:32
【问题描述】:

我希望从返回类型Either<Exception, Object> 的方法中轻松提取值。

我正在做一些测试,但无法轻松测试我的方法的返回。

例如:

final Either<ServerException, TokenModel> result = await repository.getToken(...);

为了测试我能做到这一点

expect(result, equals(Right(tokenModelExpected))); // => OK

现在如何直接检索结果?

final TokenModel modelRetrieved = Left(result); ==> Not working..

我发现我必须这样投射:

final TokenModel modelRetrieved = (result as Left).value; ==> But I have some linter complain, that telling me that I shouldn't do as to cast on object...

我也想测试异常但它不起作用,例如:

expect(result, equals(Left(ServerException()))); // => KO

所以我尝试了这个

expect(Left(ServerException()), equals(Left(ServerException()))); // => KO as well, because it says that the instances are different.

【问题讨论】:

    标签: unit-testing flutter dart either


    【解决方案1】:

    好的,我的问题的解决方案在这里:

    提取/检索数据

    final Either<ServerException, TokenModel> result = await repository.getToken(...);
    result.fold(
     (exception) => DoWhatYouWantWithException, 
     (tokenModel) => DoWhatYouWantWithModel
    );
    
    //Other way to 'extract' the data
    if (result.isRight()) {
      final TokenModel tokenModel = result.getOrElse(null);
    }
    

    测试异常

    //You can extract it from below, or test it directly with the type
    expect(() => result, throwsA(isInstanceOf<ServerException>()));
    

    【讨论】:

    • 我如何从这里产生一些东西。喜欢:(异常)=> 产生 DoWhatYouWantWithException,(tokenModel)=> 产生 DoWhatYouWantWithModel
    • 你可以'yield result.fold(failure) => Left(failure), (token){return Right(token)});' @GaneshGhodake
    【解决方案2】:

    我无法发表评论......但也许你可以看看这个post。它不是同一种语言,但看起来是相同的行为。

    祝你好运。

    【讨论】:

    • 谢谢,我通过您的链接找到了解决方案。哲学还是一样的。我会发布答案
    【解决方案3】:

    另一种提取值的方法是简单地转换为Option,然后转换为dart可为空:

    final Either<Exception, String> myEither = Right("value");
    
    final String? myValue = myEither.toOption().toNullable();
    

    如果你喜欢,你可以定义一个简单的扩展来快捷方式:

    extension EitherHelpers<L, R> on Either<L, R> {
      R? unwrapRight() {
        return toOption().toNullable();
      }
    }
    

    【讨论】:

      【解决方案4】:
        Future<Either<Failure, FactsBase>> call(Params params) async {
      final resulting = await repository.facts();
      return resulting.fold(
        (failure) {
          return Left(failure);
        },
        (factsbase) {
          DateTime cfend = sl<EndDateSetting>().finish;        
          List<CashAction> actions = factsbase.transfers.process(facts: factsbase, startDate: repository.today, finishDate: cfend); // process all the transfers in one line using extensions
          actions.addAll(factsbase.transactions.process(facts: factsbase, startDate: repository.today, finishDate: cfend));
          for(var action in actions) action.account.cashActions.add(action); // copy all the CashActions to the Account.
          for(var account in factsbase.accounts) account.process(start: repository.today);
          return Right(factsbase);
        },
      );
      

      }

      【讨论】:

      • 虽然此代码可能会解决问题,但 including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释,并说明适用的限制和假设。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多