gpt4 book ai didi

java - 使用Spock和Robospock进行单元测试以创建SQLite数据库

转载 作者:IT老高 更新时间:2023-10-28 23:11:10 29 4
gpt4 key购买 nike

spock-core:0.7-groovy-2.0
robospock:0.5.0
Android Studio 0.8.2
Fedora release 20 (Heisenbug)

这是完整的解决方案。现在,它可以成功编译并运行单元测试,并且目录结构与预览编辑相同。请随意评论任何看起来不正确的内容。

编辑解决方案=====

build.gradle:
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'
}

SnapzClientTest.groovy:
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
}
}

SnapzAndroidDB.java,与8月5日相比没有变化
Edit 5 August ================

基本上,我试图创建一个将在具有 SQLite功能的Android应用中使用的JAR文件,因此我可以将此 JAR文件用于许多应用。

我从头开始,创建了一个更小的错误修复程序。这是目录结构,只有三个文件:
testSQLite/build.gradle
testSQLite/src/main/java/com/example/sqltest/SnapzAndroidDB.java
testSQLite/src/test/groovy/SnapzClientTest.groovy

build.gradle
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'
}

SnapzAndroidDB.java
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 */
}
}

SnapzClientTest.groovy
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
}
}

我仍然收到的错误如下:
com.example.DataAccess.SnapClientTest > Create an SQLite database for Android FAILED
java.lang.RuntimeException: Stub!
at android.database.sqlite.SQLiteOpenHelper.<init>(SQLiteOpenHelper.java:4)
at com.example.DataAccess.SnapzAndroidDB.<init>(SnapzAndroidDB.java:26)
at com.example.DataAccess.SnapClientTest.Create a sqlite database for Android(SnapzClientTest.groovy:15)

编辑8月4日===================

这是我更新的测试规范,它使用Robolectric生成可以在SQLiteOpenHelper(...)的构造函数中使用的上下文。
import org.robolectric.Robolectric

def 'Create an SQLite database for Android'() {
setup:
def androidDB = new SnapzAndroidDB(Robolectric.application)

expect:
androidDB != null
}

我实际测试的功能是扩展 SQLiteOpenHelper的类。我的构造函数 SnapzAndroidDB(...)调用 SQLiteOpenHelper()构造函数,如您所见,上下文是从测试规范传递的第一个参数:
public class SnapzAndroidDB extends SQLiteOpenHelper
public SnapzAndroidDB(Context context) {
super(context, SnapzContract.DB_NAME, null, SnapzContract.DB_VERSION);
}
.
.
}

当我运行测试时,出现以下错误:
com.sunsystem.HttpSnapClient.SnapClientTest > Create an SQLite database for Android FAILED
java.lang.RuntimeException: Stub!
at android.database.sqlite.SQLiteOpenHelper.<init>(SQLiteOpenHelper.java:4)
at com.sunsystem.DataAccess.SnapzAndroidDB.<init>(SnapzAndroidDB.java:33)
at com.sunsystem.HttpSnapClient.SnapClientTest.Create a sqlite database for Android(SnapClientTest.groovy:168)

结束编辑======================

编辑====

当我尝试使用getBaseContext()时,出现以下错误:
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)

我的规范spock函数是这样的:
def 'Create an SQLite database for Android'() {
setup:
def androidDB = new SnapzAndroidDB(getBaseContext())

expect:
androidDB != null
}

这里是依赖项:
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'
}

====

我正在为用Java编写的库进行Spock单元测试,该库将在我的Android应用程序中使用。

Java JAR文件,将部署到Android应用程序中以执行数据库任务。这是我正在测试的JAR文件。

我已经编写了一个Spock规范来测试SQLite数据库的创建。

在我的Java JAR文件中,我有一个创建SQLite数据库的类,我想在我的Spock单元测试中对其进行测试。

但是,问题在于 SQLiteOpenHelper构造函数需要使用Context进行调用,而我试图在我的Spock单元测试中使用 import android.text.mock.MockContext来模拟该上下文。
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);
}
.
.
}

现在在我的单元测试规范中,我在SnapClientTest.groovy中有以下内容:
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
}

从中可以看到,我正在模拟上下文并将其作为参数发送给将调用SQLiteOpenHelper构造函数的类的构造函数。

运行单元测试时出现的错误是:
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.

作为Spock的新手,我不确定这是否可行,因为我只是在测试我的JAR文件。

最佳答案

您面临的问题是获得用于创建数据库的正确上下文。

您第一次尝试使用getBaseContext()无效,因为它没有在SnapClientTest中找到类似的功能:“方法无签名”

在您的第二次尝试中,您将创建MockContext的实例-这是一个 stub 实现,您不能直接使用它。

http://developer.android.com/reference/android/test/mock/MockContext.html
“一个模拟的Context类。所有方法均不起作用,并抛出UnsupportedOperationException。”

尝试:

def androidDB = new SnapzAndroidDB(Robolectric.application)

http://robospock.org/ Robolectric.application进行编码应该提供一个有效的上下文。

更新
我只是注意到您没有扩展RoboSpecification,而是Specification:
import pl.polidea.robospock.RoboSpecification


class SnapClientTest extends RoboSpecification

关于java - 使用Spock和Robospock进行单元测试以创建SQLite数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24901978/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com