如何为 jdbc 模拟上下文数据源
how to mock context datasource for jdbc
我有这段代码可以连接到由 Struts 应用程序定义的数据库。
public void initConnection()
{
if (this.con == null) {
try
{
Context ctx = new InitialContext();
Context envContext = (Context)ctx.lookup("java:comp/env");
this.ds = ((DataSource)envContext.lookup("jdbc/FooBar"));
if (this.ds != null)
{
this.con = this.ds.getConnection();
if (this.con != null) {
LOGGER.info("datasbase connection established");
} else {
LOGGER.error("there was an error during connectiong to the database");
}
}
}
catch (Exception e)
{
LOGGER.error(e);
}
}
}
现在,上下文是使用 context.xml!
定义的
<Context>
<Resource name="jdbc/FooBar" auth="Container" type="javax.sql.DataSource"
maxActive="20" maxIdle="30" maxWait="10000" username="root" password=""
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/ProductiveDB?autoReconnect=true" />
</Context>
有什么方法可以使用 Java 模拟这个上下文吗?我正在编写单元测试,我需要连接到一个名为 TestDB
.
的数据库
编辑:
我正在使用 mockito 创建模拟我的 类。我只想使用 Java 创建类似于 XML 的内容,例如:
Resource resource = new Resource();
resource.setAuth("Container");
bla bla bla
resource.setURL("jdbc:mysql://localhost:3306/TestDB?aztoReconnect=true");
然后使用
将其添加到我的上下文中
new InitialContext().addToContext("jdbc/FooBar",resource);
编辑二:
我在我的设置函数中编辑了我的代码,如下所示:
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/FooBar");
ds.setUsername("root");
ds.setPassword("");
Context ctx = new InitialContext();
System.out.println(ctx);
System.out.println(ctx.getEnvironment());
ctx.addToEnvironment("java:comp/env/jdbc/FooBar", ds);
我想,这样,我离我的解决方案更近了,但现在我得到以下错误:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.getEnvironment(Unknown Source)
at com.foo.bar.su.tests.StepDefs.prepareTests(StepDefs.java:55)
at com.foo.bar.su.tests.HomeTest.setUp(HomeTest.java:22)
我想通了,这个错误显然意味着我的环境。无法找到。但是我怎样才能 "create" 它,或者什么?
我使用 JMockit(我最喜欢的模拟工具包)来做这个。
@Mocked(stubOutClassInitialization=true) final InitialContext unused = null;
编辑 1:
在另一种情况下,我有这样的事情:
new Expectations() {
InitialContext ctx;
{
...
ctx = new InitialContext(); // expect constructor
ctx.lookup(anyString); result = myMockThingie;
...
}
}
在我的案例中,我对连接到备用数据库并不特别感兴趣,因此这并不是您想要的情况,尽管它似乎很容易根据您的需要进行定制。
编辑 2:
再考虑一下,也许您可以在这里完全避免嘲笑。为什么不只是为了测试的目的,创建一个测试对象的 subclass 并覆盖 initConnection() 方法以使用您想要的连接?我经常使用这种技术,也许这对你来说是最简单的事情。请注意,您可以在测试 class 中创建一个静态内部 class 子class 测试主题,因此不用担心使用专门用于测试的工件使您的生产代码混乱。希望对您有所帮助!
您应该避免以编程方式查找,因为这会使您的代码更难测试。最好使用框架来控制依赖注入。然后你可以使用类似 DBUnit 的东西。
如果无法使用依赖项注入,您仍然可以使代码更易于测试。例如,您可以按如下方式隔离数据源查找:
public abstract class MyAbstractDao {
private DataSource ds = null;
protected DataSource getDataSource() {
if (ds == null) {
Context ctx = new InitialContext();
Context envContext = (Context)ctx.lookup("java:comp/env");
return (DataSource)envContext.lookup("jdbc/FooBar");
}
return ds;
}
public void setDataSource(DataSource ds) {
this.ds = ds;
}
}
编辑:例如,您可以使用 apache DBCP 并以编程方式创建数据源:
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/TestDB");
ds.setUsername("root");
ds.setPassword("");
现在您可以注入测试中使用的所需数据源
我有这段代码可以连接到由 Struts 应用程序定义的数据库。
public void initConnection()
{
if (this.con == null) {
try
{
Context ctx = new InitialContext();
Context envContext = (Context)ctx.lookup("java:comp/env");
this.ds = ((DataSource)envContext.lookup("jdbc/FooBar"));
if (this.ds != null)
{
this.con = this.ds.getConnection();
if (this.con != null) {
LOGGER.info("datasbase connection established");
} else {
LOGGER.error("there was an error during connectiong to the database");
}
}
}
catch (Exception e)
{
LOGGER.error(e);
}
}
}
现在,上下文是使用 context.xml!
定义的<Context>
<Resource name="jdbc/FooBar" auth="Container" type="javax.sql.DataSource"
maxActive="20" maxIdle="30" maxWait="10000" username="root" password=""
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/ProductiveDB?autoReconnect=true" />
</Context>
有什么方法可以使用 Java 模拟这个上下文吗?我正在编写单元测试,我需要连接到一个名为 TestDB
.
编辑: 我正在使用 mockito 创建模拟我的 类。我只想使用 Java 创建类似于 XML 的内容,例如:
Resource resource = new Resource();
resource.setAuth("Container");
bla bla bla
resource.setURL("jdbc:mysql://localhost:3306/TestDB?aztoReconnect=true");
然后使用
将其添加到我的上下文中new InitialContext().addToContext("jdbc/FooBar",resource);
编辑二: 我在我的设置函数中编辑了我的代码,如下所示:
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/FooBar");
ds.setUsername("root");
ds.setPassword("");
Context ctx = new InitialContext();
System.out.println(ctx);
System.out.println(ctx.getEnvironment());
ctx.addToEnvironment("java:comp/env/jdbc/FooBar", ds);
我想,这样,我离我的解决方案更近了,但现在我得到以下错误:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.getEnvironment(Unknown Source)
at com.foo.bar.su.tests.StepDefs.prepareTests(StepDefs.java:55)
at com.foo.bar.su.tests.HomeTest.setUp(HomeTest.java:22)
我想通了,这个错误显然意味着我的环境。无法找到。但是我怎样才能 "create" 它,或者什么?
我使用 JMockit(我最喜欢的模拟工具包)来做这个。
@Mocked(stubOutClassInitialization=true) final InitialContext unused = null;
编辑 1: 在另一种情况下,我有这样的事情:
new Expectations() {
InitialContext ctx;
{
...
ctx = new InitialContext(); // expect constructor
ctx.lookup(anyString); result = myMockThingie;
...
}
}
在我的案例中,我对连接到备用数据库并不特别感兴趣,因此这并不是您想要的情况,尽管它似乎很容易根据您的需要进行定制。
编辑 2: 再考虑一下,也许您可以在这里完全避免嘲笑。为什么不只是为了测试的目的,创建一个测试对象的 subclass 并覆盖 initConnection() 方法以使用您想要的连接?我经常使用这种技术,也许这对你来说是最简单的事情。请注意,您可以在测试 class 中创建一个静态内部 class 子class 测试主题,因此不用担心使用专门用于测试的工件使您的生产代码混乱。希望对您有所帮助!
您应该避免以编程方式查找,因为这会使您的代码更难测试。最好使用框架来控制依赖注入。然后你可以使用类似 DBUnit 的东西。
如果无法使用依赖项注入,您仍然可以使代码更易于测试。例如,您可以按如下方式隔离数据源查找:
public abstract class MyAbstractDao {
private DataSource ds = null;
protected DataSource getDataSource() {
if (ds == null) {
Context ctx = new InitialContext();
Context envContext = (Context)ctx.lookup("java:comp/env");
return (DataSource)envContext.lookup("jdbc/FooBar");
}
return ds;
}
public void setDataSource(DataSource ds) {
this.ds = ds;
}
}
编辑:例如,您可以使用 apache DBCP 并以编程方式创建数据源:
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/TestDB");
ds.setUsername("root");
ds.setPassword("");
现在您可以注入测试中使用的所需数据源