package org.jooby.mongodb; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.isA; import static org.junit.Assert.assertEquals; import org.jooby.Env; import org.jooby.Env.ServiceKey; import org.jooby.test.MockUnit; import org.jooby.test.MockUnit.Block; import org.junit.Test; import org.junit.runner.RunWith; 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.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 com.typesafe.config.ConfigValueFactory; import javaslang.control.Try.CheckedRunnable; @RunWith(PowerMockRunner.class) @PrepareForTest({Mongodb.class, MongoClient.class }) public class MongodbTest { private Config $mongodb = ConfigFactory.parseResources(getClass(), "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); }; @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(unit-> { MongoClient client = unit.get(MongoClient.class); client.close(); }) .run(unit -> { Mongodb mongodb = new Mongodb(); mongodb.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }, unit -> { unit.captured(CheckedRunnable.class).iterator().next().run(); }); } @Test(expected = IllegalArgumentException.class) public void shouldFaileWhenDbIsMissing() 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"); }) .expect(mongodb) .run(unit -> { Mongodb mongodb = new Mongodb(); mongodb.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); } @Test public void defaultsWithCustomOption() 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(true); expect(config.getConfig("mongodb.db")).andReturn(ConfigFactory.empty() .withValue("connectionsPerHost", ConfigValueFactory.fromAnyRef(50))); expect(config.getString("db")).andReturn("mongodb://127.0.0.1/mydb"); }) .expect(serviceKey(new ServiceKey())) .expect(mongodb) .run(unit -> { new Mongodb() .options((options, config) -> { assertEquals(50, options.build().getConnectionsPerHost()); }) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); } @Test public void defaultsConfig() throws Exception { new MockUnit(Env.class, Config.class, Binder.class) .run(unit -> { assertEquals($mongodb, new Mongodb().config()); }); } @Test public void defaultsWithOptions() 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) .run(unit -> { new Mongodb() .options((options, config) -> { options.connectTimeout(3000); }) .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); }; } }