Java 使用Spock和Robospock创建SQLite数据库的单元测试
这是完整的解决方案。现在它成功编译并运行单元测试,目录结构与预览编辑相同。请随意评论任何看起来不对劲的事情 编辑解决方案===== build.gradle:Java 使用Spock和Robospock创建SQLite数据库的单元测试,java,android,sqlite,unit-testing,robospock,Java,Android,Sqlite,Unit Testing,Robospock,这是完整的解决方案。现在它成功编译并运行单元测试,目录结构与预览编辑相同。请随意评论任何看起来不对劲的事情 编辑解决方案===== build.gradle: spock-core:0.7-groovy-2.0 robospock:0.5.0 Android Studio 0.8.2 Fedora release 20 (Heisenbug) SnapzClient.groovy: apply plugin: 'java' apply plugin: 'groovy' repositorie
spock-core:0.7-groovy-2.0
robospock:0.5.0
Android Studio 0.8.2
Fedora release 20 (Heisenbug)
SnapzClient.groovy:
apply plugin: 'java'
apply plugin: 'groovy'
repositories {
mavenCentral()
maven {
// Location of Android SDK for compiling otherwise get this error:
/* Could not find com.android.support:support-v4:19.0.1.
Required by:
:testSQLite:unspecified > org.robospock:robospock:0.5.0 > org.robolectric:robolectric:2.3 */
url "/home/steve/local/android-studio/sdk/extras/android/m2repository/"
}
}
dependencies {
// just compile so we can use the sqlite API
compile 'com.google.android:android:4.1.1.4', {
// Do not bring in dependencies
transitive = false
}
testCompile 'org.codehaus.groovy:groovy:2.3.+'
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
testCompile 'org.robospock:robospock:0.5.0'
testCompile 'org.robospock:robospock-plugin:0.4.0'
}
public class SnapzAndroidDB extends SQLiteOpenHelper implements SnapzDAO {
public SnapzAndroidDB(Context context) {
super(context, SnapzContract.DB_NAME, null, SnapzContract.DB_VERSION);
}
/* Called only once first time the database is created */
@Override
public void onCreate(SQLiteDatabase db) {
String sqlCreate = String.format("create table %s (%s int primary key, %s text, %s text, %s text)",
SnapzContract.TABLE,
SnapzContract.GetConfigColumn.ID,
SnapzContract.GetConfigColumn.NAME,
SnapzContract.GetConfigColumn.VALUE,
SnapzContract.GetConfigColumn.CFG_TYPE);
db.execSQL(sqlCreate);
}
.
.
}
SnapzAndroidDB.java,与8月5日的编辑相比没有任何更改
package com.example.DataAccess
import com.example.DataAccess.SnapzAndroidDB
import org.robolectric.Robolectric
import pl.polidea.robospock.RoboSpecification
class SnapClientTest extends RoboSpecification {
/* Create Sqlite database for Android */
def 'Create a sqlite database for Android'() {
setup:
def androidDB = new SnapzAndroidDB(Robolectric.application)
expect:
androidDB != null
}
}
基本上,我正在尝试创建一个JAR文件,该文件将在Android应用程序中使用,该应用程序将具有的功能,因此我可以在许多应用程序中使用该文件
我从零开始,创建了一个更容易修复bug的更小的应用程序。这是目录结构,只有三个文件:
Edit 5 August ================
格雷德尔先生
testSQLite/build.gradle
testSQLite/src/main/java/com/example/sqltest/SnapzAndroidDB.java
testSQLite/src/test/groovy/SnapzClientTest.groovy
SnapzAndroidDB.java
apply plugin: 'java'
apply plugin: 'groovy'
repositories {
mavenCentral()
maven {
// Location of Android SDK for compiling otherwise get this error:
/* Could not find com.android.support:support-v4:19.0.1.
Required by:
:testSQLite:unspecified > org.robospock:robospock:0.5.0 > org.robolectric:robolectric:2.3 */
url "/home/steve/local/android-studio/sdk/extras/android/m2repository/"
}
}
dependencies {
// Just compile so we can use the sqlite API
compile 'com.google.android:android:4.1.1.4', {
// Do not bring in dependencies
transitive = false
}
testCompile 'org.codehaus.groovy:groovy:2.3.+'
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
testCompile 'org.robospock:robospock:0.5.0'
testCompile 'org.robospock:robospock-plugin:0.4.0'
}
SnapzClient.groovy
package com.example.DataAccess;
import java.util.logging.ConsoleHandler;
import java.util.logging.SimpleFormatter;
import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.logging.Level;
import android.content.Context;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteException;
import android.database.Cursor;
public class SnapzAndroidDB extends SQLiteOpenHelper {
/**
* Logger for displaying log messages
*/
private static final Logger log = Logger.getLogger("SnapzAndroidDB");
private SQLiteDatabase mDb;
public SnapzAndroidDB(Context context) {
super(context, "DB_NAME", null, 1);
/* Create logger */
ConsoleHandler consoleHandler = new ConsoleHandler();
log.addHandler(consoleHandler);
log.setLevel(Level.FINE);
consoleHandler.setFormatter(new SimpleFormatter());
consoleHandler.setLevel(Level.ALL);
log.log(Level.INFO, "SnapzAndroidDB()");
}
/* Called only once first time the database is created */
@Override
public void onCreate(SQLiteDatabase mDb) {
log.log(Level.INFO, "onCreate(SQLiteDatabase db)");
String createConfig = String.format("create table %s (%s int primary key, %s text, %s text)",
"TABLE_CONFIG",
"ID",
"NAME",
"VALUE");
log.log(Level.INFO, "onCreate with SQL: " + createConfig);
mDb.execSQL(createConfig);
}
@Override
public void onUpgrade(SQLiteDatabase mDb, int oldVersion, int newVersion) {
log.log(Level.INFO, "onUpgrade()");
/* Only if there is some schema changes to the database */
}
}
我仍然收到以下错误:
package com.example.DataAccess
import com.example.DataAccess.SnapzAndroidDB
import spock.lang.Specification
import org.robolectric.Robolectric
class SnapClientTest extends Specification {
/* Create SQLite database for Android */
def 'Create an SQLite database for Android'() {
setup:
def androidDB = new SnapzAndroidDB(Robolectric.application)
expect:
androidDB != null
}
}
我实际测试的函数是一个扩展了SQLiteOpenHelper
的类。我的构造函数SnapzAndroidDB(…)
调用SQLiteOpenHelper()
constructor,您可以看到上下文是从测试规范传递的第一个参数:
import org.robolectric.Robolectric
def 'Create an SQLite database for Android'() {
setup:
def androidDB = new SnapzAndroidDB(Robolectric.application)
expect:
androidDB != null
}
当我运行测试时,出现以下错误:
public class SnapzAndroidDB extends SQLiteOpenHelper
public SnapzAndroidDB(Context context) {
super(context, SnapzContract.DB_NAME, null, SnapzContract.DB_VERSION);
}
.
.
}
我的规范spock功能如下:
com.sunsystem.HttpSnapClient.SnapClientTest > Create an SQLite database for Android FAILED
groovy.lang.MissingMethodException: No signature of method: com.sunsystem.HttpSnapClient.SnapClientTest.getBaseContext() is applicable for argument types: () values: []
at com.sunsystem.HttpSnapClient.SnapClientTest.Create a sqlite database for Android(SnapClientTest.groovy:159)
以下是依赖项:
def 'Create an SQLite database for Android'() {
setup:
def androidDB = new SnapzAndroidDB(getBaseContext())
expect:
androidDB != null
}
====
我正在为用Java编写的库进行Spock单元测试,该库将用于我的Android应用程序
javajar文件将被部署到Android应用程序中,用于执行数据库操作。我正在测试的就是这个JAR文件
我已经编写了一个Spock规范,用于测试SQLite数据库的创建
在我的javajar文件中,我有一个创建SQLite数据库的类,我想在Spock单元测试中测试它
dependencies {
compile "com.googlecode.json-simple:json-simple:1.1.1", {
// Exclude junit as we don't want this include in our JAR file as it will add hamcast and other dependencies as well
exclude group:'junit', module: 'junit'
}
// Just compile so we can use the SQLite API. This won't be included in the JAR
compile 'com.google.android:android:4.1.1.4', {
// Do not bring in dependencies
transitive = false
}
// Compile for unit testing only
testCompile "org.codehaus.groovy:groovy:2.3.4"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
testCompile 'org.robospock:robospock:0.5.0'
testCompile 'com.google.android:android-test:4.1.1.4'
testCompile 'com.android.tools.build:gradle:0.12.2'
testCompile 'org.robospock:robospock-plugin:0.4.0'
}
但是,问题是需要使用上下文调用SQLiteOpenHelper
构造函数,我正在Spock单元测试中尝试使用import android.text.mock.MockContext
模拟该上下文
dependencies {
compile "com.googlecode.json-simple:json-simple:1.1.1", {
// Exclude junit as we don't want this include in our JAR file as it will add hamcast and other dependencies as well
exclude group:'junit', module: 'junit'
}
// Just compile so we can use the SQLite API. This won't be included in the JAR
compile 'com.google.android:android:4.1.1.4', {
// Do not bring in dependencies
transitive = false
}
// Compile for unit testing only
testCompile "org.codehaus.groovy:groovy:2.3.4"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
testCompile 'org.robospock:robospock:0.5.0'
testCompile 'com.google.android:android-test:4.1.1.4'
testCompile 'com.android.tools.build:gradle:0.12.2'
testCompile 'org.robospock:robospock-plugin:0.4.0'
}
现在,在我的单元测试规范中,SnapClientTest.groovy中有以下内容:
apply plugin: 'java'
apply plugin: 'groovy'
repositories {
mavenCentral()
maven {
// Location of Android SDK for compiling otherwise get this error:
/* Could not find com.android.support:support-v4:19.0.1.
Required by:
:testSQLite:unspecified > org.robospock:robospock:0.5.0 > org.robolectric:robolectric:2.3 */
url "/home/steve/local/android-studio/sdk/extras/android/m2repository/"
}
}
dependencies {
// just compile so we can use the sqlite API
compile 'com.google.android:android:4.1.1.4', {
// Do not bring in dependencies
transitive = false
}
testCompile 'org.codehaus.groovy:groovy:2.3.+'
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
testCompile 'org.robospock:robospock:0.5.0'
testCompile 'org.robospock:robospock-plugin:0.4.0'
}
public class SnapzAndroidDB extends SQLiteOpenHelper implements SnapzDAO {
public SnapzAndroidDB(Context context) {
super(context, SnapzContract.DB_NAME, null, SnapzContract.DB_VERSION);
}
/* Called only once first time the database is created */
@Override
public void onCreate(SQLiteDatabase db) {
String sqlCreate = String.format("create table %s (%s int primary key, %s text, %s text, %s text)",
SnapzContract.TABLE,
SnapzContract.GetConfigColumn.ID,
SnapzContract.GetConfigColumn.NAME,
SnapzContract.GetConfigColumn.VALUE,
SnapzContract.GetConfigColumn.CFG_TYPE);
db.execSQL(sqlCreate);
}
.
.
}
从中可以看出,我正在模拟上下文,并将其作为参数发送给类的构造函数,该类将调用SQLiteOpenHelper构造函数
运行单元测试时出现的错误如下:
import android.test.mock.MockContext
def 'Create an SQLite database for Android'() {
setup:
def context = new MockContext()
def androidDB = new SnapzAndroidDB(context.getApplicationContext())
expect:
androidDB != null
}
com.HttpSnapClient.SnapClientTest>为Android创建SQLite数据库失败
11:05:27.062[DEBUG][TestEventLogger]java.lang.RuntimeException:存根!
11:05:27.063[DEBUG][TestEventLogger]位于android.content.Context.(Context.java:4)
11:05:27.063[DEBUG][TestEventLogger]位于android.test.mock.MockContext.(MockContext.java:5)
11:05:27.063[DEBUG][TestEventLogger]位于com.sunsystem.HttpSnapClient.SnapClientTest.为Android创建sqlite数据库(SnapClientTest.groovy:155)
11:05:27.065[QUIET][system.out]11:05:27.064[DEBUG][org.gradle.process.internal.child.ActionExecutionWorker]正在停止客户端连接。
作为Spock的新手,我不确定这是否可行,因为我只是在测试我的JAR文件。Spock是Groovy和Java生态系统中使用最广泛的框架之一,它允许使用非常直观的语言创建测试,并促进一些常见任务,如模拟和可扩展性。它之所以在人群中脱颖而出,是因为它的规范语言优美且极具表现力。由于其JUnit runner,Spock与大多数IDE、构建工具和持续集成服务器兼容。要使用Spock,您基本上需要执行一组步骤,例如遵循一个步骤,这将允许您有效地实现单元测试和web集成 您当前的错误消息如下:
com.HttpSnapClient.SnapClientTest > Create an SQLite database for Android FAILED
11:05:27.062 [DEBUG] [TestEventLogger] java.lang.RuntimeException: Stub!
11:05:27.063 [DEBUG] [TestEventLogger] at android.content.Context.<init>(Context.java:4)
11:05:27.063 [DEBUG] [TestEventLogger] at android.test.mock.MockContext.<init>(MockContext.java:5)
11:05:27.063 [DEBUG] [TestEventLogger] at com.sunsystem.HttpSnapClient.SnapClientTest.Create a sqlite database for Android(SnapClientTest.groovy:155)
11:05:27.065 [QUIET] [system.out] 11:05:27.064 [DEBUG] [org.gradle.process.internal.child.ActionExecutionWorker] Stopping client connection.
请尝试以下步骤,看看效果如何:
包括到您的代码中,应该有助于:
Create a sqlite database for Android FAILED
这样,Android将能够管理和缓存数据
但是,如果您从getBaseContext收到任何错误消息,请尝试卸载测试插件,并使用integrate with--eclipse重新创建STS资源(.classpath&.project),那么它应该会
如果您对getSpecificationContext有任何问题,这意味着遗漏了一些细节,您需要再次检查您的配置
如果您不使用spock创建文件,您可以通过命令行工具将其与Emacs连接,例如Sun的JDK或任何其他预期的方法。要仅运行SampleTest,必须使用以下属性从命令行调用测试任务:
jokesHelper dbHelper = new jokesHelper(getBaseContext());
SQLiteDatabase db = dbHelper.getWritableDatabase();
或者
gradle -Dtest.single=Sample test
还要检查正在使用的目录上有哪些内容。如果您尚未完成,请记住包括:
并通知测试目录您是,例如srcDirs。请记住(“Esist wichtig das man hier die richtige Resources Klasse importiert”)导入类所需的。同样,对于“defaultConfig”中的“build.gradle”:
和是创新工具,可以帮助开发有用的资源。或者,您也可以使用诸如TCL测试之类的工具。TCL测试是最古老的测试集,也是您可以采取的最佳方法。事实上,SQLite最初是作为Tcl扩展的。SQLite的许多测试和开发工具都是用Tcl编写的。除了本机C API之外,Tcl扩展是核心SQLite团队支持的唯一API
要启用Tcl绑定,请从下载SQLite源代码的TEA(Tcl扩展体系结构)发行版。此版本的代码本质上是与
附加到末尾的Tcl绑定。这将构建到Tcl扩展中,然后可以将其导入到任何Tcl环境中
应该遵循非常具体的步骤,并注意每一个步骤是至关重要的,因为它可以使您的测试成功运行或不成功
是测试框架的基础。 仪表控制被测应用,并允许
dependencies {
classpath 'com.android.tools.build:gradle:0.8.+'
classpath 'org.robospock:robospock-plugin:0.4.0'
}
testPackageName "com.yourpackage.test"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
testFunctionalTest true
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aatg.sample.test"
android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/icon"
android:label="@string/app_name">
<uses-library android:name="android.test.runner" />
</application>
<uses-sdk android:minSdkVersion="7" />
<instrumentation
android:targetPackage="com.example.aatg.sample
android:name="android.test.InstrumentationTestRunner"
android:label="Sample Tests" />
<uses-permission android:name="
android.permission.INJECT_EVENTS" />
</manifest>
int sqlite3_load_extension( sqlite3 *db, const char *ext_name,
const char *entry_point, char **error )
load_extension( 'ext_name' )
load_extension( 'ext_name', 'entry_point' )
def androidDB = new SnapzAndroidDB(Robolectric.application)
import pl.polidea.robospock.RoboSpecification
class SnapClientTest extends RoboSpecification