为什么我从Spock测试中回调的次数太少?

时间:2016-01-29 16:53:51

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

我是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()
}

非常感谢任何帮助。我已经在我能想到的每一种配置中尝试了这一点......它总是有同样的问题。

1 个答案:

答案 0 :(得分:1)

自问题发布以来已经有一段时间了,但无论如何我都会尽力回答。

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