【问题标题】:Why am I getting too few invocations back from this Spock test?为什么我从这个 Spock 测试中得到的调用太少了?
【发布时间】:2016-01-29 16:53:50
【问题描述】:

我是 Spock 测试框架的新手,我正在尝试对我正在开发的一个 android 项目进行一些测试。我目前正在测试的这些对象是 PJO,因此可以使用常规 Spock 对其进行测试。出于某种原因,我在我的一个对象上调用的 isAlive 方法不断得到 0 次调用,但我知道它已被调用,因为我确实在调试器中运行了它并调用了它。所以我希望有人能引导我知道我做错了什么。

这是我正在测试的代码:

 public void start(int startIndex, boolean overrideDownloadOnCellNetwork){
        this.downloadIndex = startIndex;
        this.overrideDownloadOnCellNetwork = overrideDownloadOnCellNetwork;
        if(checkConnectionType(overrideDownloadOnCellNetwork)){
            this.startTrackDownload();
        }
    }

    // I should simplify this at some point.
    private boolean checkConnectionType(boolean overrideDownloadOnCellNetwork) {
        ConnectivityManager connManager = (ConnectivityManager) masterService.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo connection = connManager.getActiveNetworkInfo();
        if(connection == null){
           broadcaster.broadcastError(DownloadEvent.DownloadEventType.ERROR_NO_NETWORK, downloadIndex);
            this.masterService.stop();
            return false;
        } else if(connection.getType() == ConnectivityManager.TYPE_MOBILE && (userModel.isCellDownloadsAllowed() || overrideDownloadOnCellNetwork)){
            return true;
        } else if (connection.getType() == ConnectivityManager.TYPE_WIFI){
            return true;
        } else {
            broadcaster.broadcastError(DownloadEvent.DownloadEventType.ERROR_NO_WIFI_CELL_DOWNLOAD_NOT_ALLOWED, downloadIndex);
            this.masterService.stop();
            return false;
        }
    }


    private void startTrackDownload(){
        if(trackList.size() > 0) {
            if (!downloadThread.isAlive()) {
                downloadThread.start();
            }
            downloadThread.downloadTrack(downloadIndex, trackList.size(), bookModel.getBookID(), userModel.getSessionID());
        }
    }

这是我的测试代码:

DownloaderImp downloader // this is a POJO

MasterService masterService
ActiveBookFactory activeBook
TrackListSubscriber trackListSubscriber
UserModel userModel
TrackSaver trackSaver
Notification notification
BookSaver bookSaver
BookModel bookModel

DownloadEventBroadcaster eventBroadcaster
DownloadThread downloadThread

Context context;


def "setup"(){

    masterService = Mock(MasterService)
    trackListSubscriber = Mock(TrackListSubscriber)
    userModel = Mock(UserModel )
    trackSaver = Mock(TrackSaver )
    notification = Mock(Notification )
    bookSaver = Mock(BookSaver)
    bookModel = Mock(BookModel)
    activeBook = Mock(ActiveBookFactory )
    downloadThread = Mock(DownloadThread)
    eventBroadcaster = Mock(DownloadEventBroadcaster)

    bookModel.getTrackModels() >> [new TrackModel(1), new TrackModel(2)]
    activeBook.get("downloading") >> bookModel
    bookModel.getId() >> 1

    downloader = new DownloaderImp(activeBook,
            trackListSubscriber,
            userModel,
            trackSaver,
            bookSaver,
            downloadThread,
            eventBroadcaster)

    context = Mock(Context)
    masterService.getContext() >> context
    downloader.setService(masterService)

}

def "should check if download thread is alive"(){
    given:
    def mockConnectionManager = Mock(ConnectivityManager)
    def mockNetworkInfo = Mock(NetworkInfo)
    masterService.getContext().getSystemService(Context.CONNECTIVITY_SERVICE) >> mockConnectionManager
    mockConnectionManager.getActiveNetworkInfo() >> mockNetworkInfo
    mockNetworkInfo.getType() >> ConnectivityManager.TYPE_MOBILE

    when:
    downloader.start(0, true)

    then:
    1 * downloadThread.isAlive()
}

任何帮助将不胜感激。我已经在我能想到的每一种配置中都尝试过这个......而且它总是有同样的问题。

【问题讨论】:

  • 当您逐步执行它时,它是否会终止,然后尝试评估线程是否处于活动状态?你是否满足这个条件 connection.getType() == ConnectivityManager.TYPE_MOBILE && (userModel.isCellDownloadsAllowed() || overrideDownloadOnCellNetwork)
  • @penguin 它调用 isAlive() 返回 false,因为它是一个模拟,这是模拟返回布尔返回类型的默认值,因此它继续进入 if 块并执行 @987654323 @
  • 如果 isAlive 始终评估为 false,那么您的 when then 也将始终评估为 0。
  • 这是为什么呢? when 块正在调用 start 方法,该方法将调用 startTrackDownload 方法,该方法调用 isAlive
  • downloadThread和downloader是如何创建的?

标签: java android unit-testing spock dagger-2


【解决方案1】:

这个问题发布已经有一段时间了,但无论如何我都会尝试回答。

对 Thread 对象进行单元测试是有问题的,因为 isAlive() 方法是最终布尔值(您将无法模拟它)。在您的代码中,您应该避免在内部逻辑中使用此方法。也许在这种情况下使用包装器(如接口)是个好主意,但最重要的是在测试线程时计算start()interrupt() 方法的调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 2017-05-29
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    相关资源
    最近更新 更多