I have a class that defines a method that returns a Future. The Future contains a list of class that also return a future.
class User{
Future<List<Album>> albums(){
};
}
class Album{
Future<List<Photos>> photos(){
}
};
What is the best way to mock the method in these classes when testing another class?
The class I am trying to test looks a bit like
class Presenter {
Presenter( User user){
user.albums().then( _processAlbums);
}
_processAlbums(List<Album> albums) {
albums.forEach( (album)=>album.photos.then( _processPhotos));
}
_processPhotos(List<Photo> photos) {
....stuff
}
}
I tried writing a unit test like this
class MockUser extends Mock implements User{}
class MockAlbum extends Mock implements Album{}
class MockPhoto extends Mock implements Photo{}
class MockFutureList<T> extends Mock implements Future<T>{
MockFutureList( List<T> items){
when( callsTo( "then")).thenReturn( items);
}
}
void main(){
test("constuctor should request the albums from the user ",(){
MockUser user = new MockUser();
MockAlbum album = new MockAlbum();
List<Album> listOfAlbums = [ album];
MockPhoto photo = new MockPhoto();
List<Album> listOfPhotos = [ album];
user.when( callsTo( "albums")).thenReturn( new MockFutureList(listOfAlbums));
album.when( callsTo( "photos")).thenReturn( new MockFutureList( listOfPhotos));
PicasaPhotoPresentor underTest = new PicasaPhotoPresentor( view, user);
user.getLogs( callsTo( "albums")).verify( happenedOnce);
album.getLogs( callsTo( "photos")).verify( happenedOnce);
});
}
This allowed me to test that the constructor called the user.photos() method, but not that the album.photos() method was called.
I am not sure that mocking a Future is a good idea - Would it not be better to create a 'real' Future that contains a list of Mocks?
Any ideas would be very helpful!
You can do this:
when(mock.method()).thenAnswer((_) => Future.value('string'));