Java 如何在使用Spock框架在另一个类内调用时模拟类方法

Java 如何在使用Spock框架在另一个类内调用时模拟类方法,java,groovy,spock,spring-boot-test,Java,Groovy,Spock,Spring Boot Test,工作服务类: listAvailableBooks(); //should always return 0; 最后,这是我的spock groovy测试: public class WorkService { public Integer listSize(){ BookService bs = new BookService(); return bs.listAvailableBooks().size(); } } @SpringBootT

工作服务类:

listAvailableBooks(); //should always return 0;
最后,这是我的spock groovy测试:

public class WorkService {

    public Integer listSize(){
        BookService bs = new BookService();
        return bs.listAvailableBooks().size();
    }
}
@SpringBootTest
类BookServiceTests扩展了规范{
//图书服务
工作服务工作服务=新工作服务()
图书服务
def“如果没有可用的书籍,则不返回任何书籍”(){
给定:“没有书”
bookService=Stub()
何时:“检索可用图书”
bookService.listAvailableBooks()>>new ArrayList()
然后:“没有可用的书籍”
workService.listSize()==0//应为0,但返回3
}
}

BookService
作为
工作服务的构造函数的参数传入。然后你可以在TestThank@tim_yates下模拟它。但我正在编写集成测试,这是原始代码的POC,我不能更改代码。看起来你不能更改代码,不稳定的代码是不稳定的。公平地说,在这个例子中,你可以测试
BookService。listAvailableBooks()
与预期一样工作,因为被测试的方法只返回
size()
,我假设Oracle测试了它;-)我怀疑您的实际情况比示例更复杂:-(很抱歉,还有一条评论,但我刚刚发现了这个问题和这条评论:“我正在编写集成测试(…)无法更改代码。”抱歉,伙计,也许你的开发团队中有人不明白测试自动化是怎么回事。这么做的原因之一是为了发现代码中的设计缺陷,比如缺少依赖项注入导致的不好的可测试性。代码本身实例化了它的依赖项,是重构的一个迫切候选项。问题在于代码,而不是所以,不要再尝试测试了,而是让开发者重构该死的代码!
public class WorkService {

    public Integer listSize(){
        BookService bs = new BookService();
        return bs.listAvailableBooks().size();
    }
}
@SpringBootTest
class BookServiceTests extends Specification {

    //BookService bookService
    WorkService workService = new WorkService()
    BookService bookService

    def "returns no books if no books available"() {
        given: "no books"
        bookService = Stub()

        when: "retrieving available books"
        bookService.listAvailableBooks() >> new ArrayList<Book>()

        then: "there are no books available"
        workService.listSize() == 0//expecting 0, but returning 3
    }
}