Mock class that implements another class which uses Equatable - flutter

I faced a problem while mocking a class for testing. The problem is my class extends euqatable. And when I try to mock it I see the warning: Don't implement classes that override "==". I'm searching for a solution that solves this warning without using ignore or completely filling up models using super as it's recommended in avoid_implementing_value_types rule doc. Just creating mock as it usually is with some small additional code snippet. Here is the example of the code that causes the warning:
class MyEquatableClass extends Equatable {
#override
List<Object?> get props => [];
}
class MockMyEquatableClass extends Mock implements MyEquatableClass {}

Well, it's said in mockito's documentation that it's prefered to create your mocks using code generation instead of the old extends Mock, by doing so I don't get any warning:
import 'package:equatable/equatable.dart';
import 'package:mockito/annotations.dart';
import 'mock_equatable_test.mocks.dart';
class MyEquatableClass extends Equatable {
const MyEquatableClass();
#override
List<Object?> get props => [];
}
#GenerateMocks([MyEquatableClass])
void main() {
final mockedClass = MockMyEquatableClass();
}
Another way of mocking your classes which is in my opinion just as good as using mockito is using the package mocktail:
import 'package:mocktail/mocktail.dart';
class MockMyEquatableClass extends Mock implements MyEquatableClass {}
While the mocking API may change a bit you'll have the same capabilities as mockito without relying on code generation.

Related

class that indirectly extends from StateNotifier in StateNotifierProvider doesn't work

I want to use a class that indirectly extends from StateNotifier in StateNotifierProvider, but it doesn't work.
import 'package:riverpod/riverpod.dart';
abstract class BaseDog {}
class Shiba extends BaseDog {}
abstract class BaseDogListController
extends StateNotifier<AsyncValue<List<BaseDog>>> {
BaseDogListController() : super(const AsyncValue.loading());
//doing something with state.
}
class ShibaListController extends BaseDogListController {}
final shibaListControllerProvider =
StateNotifierProvider<ShibaListController//←this code is error, AsyncValue<List<Shiba>>>(
(_) => ShibaListController());
here is out put:
'ShibaListController' doesn't conform to the bound 'StateNotifier<AsyncValue<List>>' of the type parameter 'Notifier'.
Try using a type that is or is a subclass of 'StateNotifier<AsyncValue<List>>'.
the use of state in BaseDogListController is the reason why it does not directly extends from StateNotifier.
How can I solve this?
The problem is how you defined your provider
It says that it uses the ShibaListController – which has for state AsyncValue<List<BaseDog>>, yet you're telling the provider that its state is defined as AsyncValue<List<Shiba>>
These types don't match.
You likely want to make BaseDogListController generic:
abstract class BaseDogListController<DogType extends BaseDog>
extends StateNotifier<AsyncValue<List<DogType>>> {
BaseDogListController() : super(const AsyncValue.loading());
//doing something with state.
}
class ShibaListController extends BaseDogListController<Shiba> {}

Missing concrete implementation 'getter Equatable' / issue with props

I am working through many of the tutorials out there on bloc with flutter and running into some inconsistencies.
I am using Android studio and creating the bloc code by using the plugin from Intellij v1.6.0.
For the bloc_event, I continue to see examples that look like this.
#immutable
abstract class FruitEvent extends Equatable {
FruitEvent([List props = const []]) : super(props);
}
When I generate my bloc files and look at the initial _event one that generates, it looks like this.
#immutable
abstract class SongEvent extends Equatable {
const SongEvent();
}
If I modify my code that is generated to include the following...
[List props = const []]) : super(props)
Then I get the following error "Too many positional arguments, 0 expected, 1 found" which references props at the end of the line shown above.
If I leave my code as it was generated by the bloc plugin, and then try to implement my events by adding in the following...
class AddSong extends SongEvent {}
Then I get an error of "Missing concrete implementation of 'getter Equatable.props'
Here is my current bloc/song_event.dart
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
#immutable
abstract class SongEvent extends Equatable {
const SongEvent();
}
class AddSong extends SongEvent {}
Question
Should I be using the line that has props in it as shown in the FuitEvent example?
I don't understand what it is I am missing here and why it shows with an error when I try to use the same method as shown in so many of the tutorials.
Equatable overrides == and hashCode for you so you don't have to waste your time writing lots of boilerplate code.
Basically it helps in doing equality comparison for Objects.
Equatable is an abstract class and it has a getter List<Object> get props;.Concrete Class who extends Equatable must override that getter.
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
#immutable
abstract class SongEvent extends Equatable {
const SongEvent();
}
class AddSong extends SongEvent {}
In this case, SongEvent is an abstract class, therefore it doesn't have to implement the props getter even tho it extends Equatable. But AddSong is a concrete class that extends SongEvent which extends Equatable, therefore AddSong has to implement the getter in Equatable.
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
#immutable
abstract class SongEvent extends Equatable {
const SongEvent();
}
// Something like this
class AddSong extends SongEvent {
final Song song;
const AddSong(this.song);
#override
List<Object> get props => [song];
}

Akka Typed and having base class for MessageAdapters

I am trying something with Akka Typed and Scala, actually something very simple as concept but I could not make it work so may be you can help me.
All my Actors will have one common Signal, so I try to place it to a base class and let my all Actors share it but it the compiler refuse it in the MessageAdapter....
So my code looks like following....
object ContractActor {
sealed trait ContractEvent extends BaseEvent
final case class onApprove(payload: Payload) extends ContractEvent
}
class ContractActor(ctx: ActorContext[ContractEvent]) extends BaseActor {
val listingAdapter = : ActorRef[Receptionist.Listing] = ctx.
messageAdapter(
listing => onAddRelatedEvent(listing)
}
and base actor
object BaseActor {
trait BaseEvent;
final case class onAddRelatedEvent(listing: Receptionist.Listing) extends BaseEvent
}
The compiler complains about onAddRelatedEvent is not known on ContractEvent which surprise me because ContractEvent extends BaseEvent....
What am I missing here....
Class ContractActor extending BaseActor does not automatically bring BaseActor's companion object into scope. To bring it into scope, just import it inside class ContractActor:
import BaseActor._
Alternatively, you could move the inner trait/case class into BaseActor's companion class.

Final clean up in specs2

I am writing a specs2 Unittest for my scala software. The execution is working well. The only problem I have, is that I need to clean up after all test are finished. I just cannot find any solution for that. Is there a way to execute some functions after all test are finished?
You need to add a Step at the end of your specification:
import org.specs2.mutable._
class MySpec extends Specification {
// lots of examples here
// cleanup there
step(cleanUp())
}
You can try to use After with After and implement def after function.
Example:
class Context extends Specification {
....
}
trait trees extends mutable.After {
def after = cleanupDB
}

Scala class with Publisher and Subscriber traits

Using import scala.collection.mutable.{Publisher, Subscriber} I'm trying to implement a class that subscribes to events and publishes events. For example, this class may receive raw data, operate on it, then publish the result to other subscribers.
A basic class that extends Subscriber:
scala> class Sub[Evt, Pub]() extends Subscriber[Evt, Pub]{
def notify(pub: Pub, evt: Evt){
}
}
defined class Sub
A basic class that extends Publisher:
scala> class Pub[Evt]() extends Publisher[Evt]{}
defined class Pub
Now, I want to combine the two:
scala> class PubSub[Evt, Pub] extends Subscriber[Evt, Pub] with Publisher[Evt]{
def notify(pub: Pub, evt: Evt){
}
}
<console>:26: error: class PubSub needs to be abstract, since method notify in
trait Subscriber of type (pub: Pub,event: Evt)Unit is not defined class
PubSub[Evt,Pub] extends Subscriber[Evt, Pub] with Publisher[Evt]{
The notify method is defined so perhaps the error is misleading.
I'm not sure how to define the type parameters for the PubSub class which might be part of the problem.
The problem is that the class Publisher defines a type Pub which shadows the generic Pub argument.
Just rename it to something else:
class PubSub[Evt, Pub2] extends Subscriber[Evt, Pub2] with Publisher[Evt]{
def notify(pub: Pub2, evt: Evt){
}
}
You should take a look at the paper Deprecating the Observer Pattern I believe. scala.react package described there isn't released as a part of the standard distribution, but some snapshot is available on the author's homepage. If you are not planning to use it in production systems right now this project can give a sufficient playground.