package org.jooby.mongodb; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.isA; import org.jooby.Env; import org.jooby.Env.ServiceKey; import org.jooby.Registry; import org.jooby.internal.mongodb.AutoIncID; import org.jooby.internal.mongodb.GuiceObjectFactory; import org.jooby.test.MockUnit; import org.jooby.test.MockUnit.Block; import org.junit.Test; import org.junit.runner.RunWith; import org.mongodb.morphia.Datastore; import org.mongodb.morphia.Morphia; import org.mongodb.morphia.mapping.Mapper; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import com.google.inject.Binder; import com.google.inject.Key; import com.google.inject.binder.AnnotatedBindingBuilder; import com.google.inject.binder.LinkedBindingBuilder; import com.google.inject.name.Names; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; import com.mongodb.client.MongoDatabase; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import javaslang.control.Try.CheckedConsumer; import javaslang.control.Try.CheckedRunnable; @RunWith(PowerMockRunner.class) @PrepareForTest({Monphia.class, Morphia.class, Mapper.class, MongoClient.class, AutoIncID.class }) public class MonphiaTest { private Config $mongodb = ConfigFactory.parseResources(Mongodb.class, "mongodb.conf"); @SuppressWarnings("unchecked") MockUnit.Block mongodb = unit -> { AnnotatedBindingBuilder<MongoClientURI> mcuABB = unit.mock(AnnotatedBindingBuilder.class); mcuABB.toInstance(isA(MongoClientURI.class)); mcuABB.toInstance(isA(MongoClientURI.class)); MongoClient client = unit.constructor(MongoClient.class) .args(MongoClientURI.class) .build(isA(MongoClientURI.class)); MongoDatabase db = unit.mock(MongoDatabase.class); expect(client.getDatabase("mydb")).andReturn(db); unit.registerMock(MongoClient.class, client); AnnotatedBindingBuilder<MongoClient> mcABB = unit.mock(AnnotatedBindingBuilder.class); mcABB.toInstance(client); mcABB.toInstance(client); AnnotatedBindingBuilder<MongoDatabase> dbABB = unit.mock(AnnotatedBindingBuilder.class); dbABB.toInstance(db); dbABB.toInstance(db); Binder binder = unit.get(Binder.class); expect(binder.bind(Key.get(MongoClientURI.class))).andReturn(mcuABB); expect(binder.bind(Key.get(MongoClientURI.class, Names.named("mydb")))).andReturn(mcuABB); expect(binder.bind(Key.get(MongoClient.class))).andReturn(mcABB); expect(binder.bind(Key.get(MongoClient.class, Names.named("mydb")))).andReturn(mcABB); expect(binder.bind(Key.get(MongoDatabase.class))).andReturn(dbABB); expect(binder.bind(Key.get(MongoDatabase.class, Names.named("mydb")))).andReturn(dbABB); Env env = unit.get(Env.class); expect(env.onStop(unit.capture(CheckedRunnable.class))).andReturn(env); }; @SuppressWarnings("unchecked") private Block objectFactory = unit -> { Env env = unit.get(Env.class); expect(env.onStart(unit.capture(CheckedConsumer.class))).andReturn(env); }; @SuppressWarnings("unchecked") private Block morphia = unit -> { MongoClient client = unit.get(MongoClient.class); Datastore ds = unit.mock(Datastore.class); unit.registerMock(Datastore.class, ds); Mapper mapper = unit.mockConstructor(Mapper.class); unit.registerMock(Mapper.class, mapper); Morphia morphia = unit.mockConstructor(Morphia.class, new Class[]{Mapper.class }, mapper); unit.registerMock(Morphia.class, morphia); expect(morphia.createDatastore(client, mapper, "mydb")).andReturn(ds); LinkedBindingBuilder<Morphia> mLBB = unit.mock(LinkedBindingBuilder.class); mLBB.toInstance(morphia); mLBB.toInstance(morphia); LinkedBindingBuilder<Datastore> dsLBB = unit.mock(LinkedBindingBuilder.class); dsLBB.toInstance(ds); dsLBB.toInstance(ds); Binder binder = unit.get(Binder.class); expect(binder.bind(Key.get(Morphia.class))).andReturn(mLBB); expect(binder.bind(Key.get(Datastore.class))).andReturn(dsLBB); expect(binder.bind(Key.get(Morphia.class, Names.named("mydb")))).andReturn(mLBB); expect(binder.bind(Key.get(Datastore.class, Names.named("mydb")))).andReturn(dsLBB); }; @Test public void defaults() throws Exception { new MockUnit(Env.class, Config.class, Binder.class) .expect(unit -> { Config config = unit.get(Config.class); expect(config.getConfig("mongodb")).andReturn($mongodb.getConfig("mongodb")); expect(config.hasPath("mongodb.db")).andReturn(false); expect(config.getString("db")).andReturn("mongodb://127.0.0.1/mydb"); }) .expect(serviceKey(new ServiceKey())) .expect(mongodb) .expect(objectFactory) .expect(morphia) .run(unit -> { new Monphia() .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); } @SuppressWarnings("unchecked") @Test public void onStart() throws Exception { new MockUnit(Env.class, Config.class, Binder.class, Registry.class) .expect(unit -> { Config config = unit.get(Config.class); expect(config.getConfig("mongodb")).andReturn($mongodb.getConfig("mongodb")); expect(config.hasPath("mongodb.db")).andReturn(false); expect(config.getString("db")).andReturn("mongodb://127.0.0.1/mydb"); }) .expect(serviceKey(new ServiceKey())) .expect(mongodb) .expect(objectFactory) .expect(morphia) .expect(unit -> { unit.constructor(GuiceObjectFactory.class) .build(unit.get(Registry.class), unit.get(Morphia.class)); }) .run(unit -> { new Monphia("db") .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }, unit -> { unit.captured(CheckedConsumer.class).iterator().next().accept(unit.get(Registry.class)); }); } @Test public void defaultsWithMorphiaCallback() throws Exception { new MockUnit(Env.class, Config.class, Binder.class) .expect(unit -> { Config config = unit.get(Config.class); expect(config.getConfig("mongodb")).andReturn($mongodb.getConfig("mongodb")); expect(config.hasPath("mongodb.db")).andReturn(false); expect(config.getString("db")).andReturn("mongodb://127.0.0.1/mydb"); }) .expect(serviceKey(new ServiceKey())) .expect(mongodb) .expect(morphia) .expect(unit -> { Morphia morphia = unit.get(Morphia.class); expect(morphia.map(MonphiaTest.class)).andReturn(morphia); }) .expect(objectFactory) .run(unit -> { new Monphia() .doWith((morphia, config) -> { morphia.map(MonphiaTest.class); }) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); } @Test public void defaultsWithDatastoreCallback() throws Exception { new MockUnit(Env.class, Config.class, Binder.class) .expect(unit -> { Config config = unit.get(Config.class); expect(config.getConfig("mongodb")).andReturn($mongodb.getConfig("mongodb")); expect(config.hasPath("mongodb.db")).andReturn(false); expect(config.getString("db")).andReturn("mongodb://127.0.0.1/mydb"); }) .expect(serviceKey(new ServiceKey())) .expect(mongodb) .expect(morphia) .expect(unit -> { Datastore ds = unit.get(Datastore.class); ds.ensureIndexes(); }) .expect(objectFactory) .run(unit -> { new Monphia() .doWith(ds -> { ds.ensureIndexes(); }) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); } @Test public void withIdGen() throws Exception { new MockUnit(Env.class, Config.class, Binder.class) .expect(unit -> { Config config = unit.get(Config.class); expect(config.getConfig("mongodb")).andReturn($mongodb.getConfig("mongodb")); expect(config.hasPath("mongodb.db")).andReturn(false); expect(config.getString("db")).andReturn("mongodb://127.0.0.1/mydb"); }) .expect(serviceKey(new ServiceKey())) .expect(mongodb) .expect(objectFactory) .expect(morphia) .expect(unit -> { Datastore ds = unit.get(Datastore.class); ds.ensureIndexes(); AutoIncID inc = unit.constructor(AutoIncID.class) .args(Datastore.class, IdGen.class) .build(ds, IdGen.GLOBAL); Mapper mapper = unit.get(Mapper.class); mapper.addInterceptor(inc); }) .run(unit -> { new Monphia().with(IdGen.GLOBAL).doWith(ds -> { ds.ensureIndexes(); }).configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); } private Block serviceKey(final ServiceKey serviceKey) { return unit -> { Env env = unit.get(Env.class); expect(env.serviceKey()).andReturn(serviceKey).times(2); }; } }