2013-05-29 48 views
13

Chúng tôi kết hợp các thử nghiệm Spock với @ContextConfiguration của Spring để chúng ta có thể xây dựng bean trong một bối cảnh mùa xuân và sau đó sử dụng Spock để thử nghiệm thực tế. Chúng tôi muốn tiêm mock vào đậu mùa xuân của chúng tôi. Đối với Mockito, có một tiện ích mở rộng cho phép bạn thực hiện những việc như:Làm thế nào để tạo các mock Spock bên ngoài một lớp đặc tả?

<mockito:mock id="accountService" class="org.kubek2k.account.DefaultAccountService" /> 

và sau đó tham khảo giả này với các loại đậu xuân khác. Có vẻ như không có phần mở rộng như vậy cho Spock. Sau đó, một lần nữa xây dựng này có lẽ không phải là quá nhiều nỗ lực nếu bạn biết cách tạo Mocks bên ngoài lớp Đặc tả. Cách duy nhất để tạo mô hình Spock mà tôi biết là:

T Mock(Class<T> type) 

trong Đặc điểm kỹ thuật. Có một số API trong Spock để tạo ra Mocks khi không ở trong lớp Đặc tả, vì vậy tôi có thể tạo ra các mock Spock cho một bối cảnh mùa xuân?

Trả lời

6

Tạo mocks bên ngoài một lớp đặc tả (và sử dụng chúng trong lớp đặc tả khác) hiện không khả thi. Có một yêu cầu tính năng mở cho việc này. Nó không phải là quá khó để thực hiện điều này, nhưng nó sẽ đòi hỏi một số thay đổi để spock-core. Ít nhất, sẽ cần phải có cách để tự gắn một đối tượng giả vào một thể hiện cụ thể khác. Có lẽ, cũng sẽ có ý nghĩa khi di chuyển API tạo giả tạo người dùng ra khỏi lớp cơ sở MockingApi.

Bạn có thể sử dụng Mockito với Spock, miễn là bạn quấn tất cả mã xác minh có trong khối sau đó bằng một cuộc gọi đến phương thức trợ giúp trả về true (vì Spock sẽ coi đó là xác nhận). Một cái gì đó như then: mockito { /* mockito verifications go here */ }.

+4

Tôi đang ngồi trong SpringOne Spock & testMvc sess ion và nó bắt đầu cảm thấy rõ ràng rằng để trộn lẫn trong một số dịch vụ được mô phỏng, và một số dịch vụ được cấu hình bởi Spring (ví dụ để tránh có logic tích hợp bên ngoài thử nghiệm) tính năng này sẽ rất hữu ích. –

+0

Có lẽ SpecificationMixin là những gì tôi đang tìm kiếm? –

+0

Tôi không quen với 'SpecificationMixin'. Có một yêu cầu kéo trong các công trình cho phép xây dựng bên ngoài của mocks, và hy vọng nó sẽ được phát hành với phiên bản Spock tiếp theo. –

5

Tìm cách giải quyết đơn giản để sử dụng đối tượng giả lập Spock trong ứng dụng Spring. Dưới đây cấu hình mùa xuân của tôi sử dụng một mô hình cho đậu Basar:

@Configuration @Profile("mocking") 
class MockingContext { 
    @Bean Basar basar(){ new DelegatingBasar() } 
} 

class DelegatingBasar implements Basar { 
    @Delegate Basar delegate 
} 

Và đây là một đặc điểm kỹ thuật Spock đơn giản mà tạo ra và sử dụng một mô hình:

@Autowired 
Basar basar 
Basar basarMock 

def setup() { 
    basarMock = Mock(Basar) 
    basar.delegate = basarMock; 
} 

def "create a new seller"(User seller) { 
    given: 
     basarMock.findAllUsers() >> [] 
    when: 
     go "/static/sellers.html" 
     waitFor { $("#newUser") } 
     $("#newUser").click() 
     waitFor { $("#basarNumber") } 
     $("#basarNumber").value(seller.basarNumber) 
     $("#name").value(seller.name) 
     $("#lastname").value(seller.lastname) 
     $("#email").value(seller.email) 
     $("#saveUser").click() 
     waitFor { $("#successfullCreated") } 
    then: 
     1 * basarMock.saveUser({ newUser -> 
      newUser.basarNumber == seller.basarNumber 
      newUser.name  == seller.name 
      newUser.lastname == seller.lastname 
      newUser.email  == seller.email 
     }) 
    where: 
     seller << [ new User(basarNumber: "100", name: "Christian", lastname: "", email: ""), 
        new User(basarNumber: "ABC", name: "",   lastname: "", email: "")] 
} 
+1

Đó là cách giải quyết gọn gàng :). Trong khi đó, chúng tôi đã chuyển sang một cách tiếp cận nhẹ hơn mặc dù. Chúng tôi cố gắng tránh xa hoàn toàn việc xây dựng bối cảnh mùa xuân trong các bài kiểm tra đơn vị của mình và chỉ đơn giản là tự mình lấy ra tất cả các phụ thuộc (xem https://gist.github.com/derkork/45d7fba64b54a41608e1). Điều này đã làm tăng đáng kể thông lượng thử nghiệm của chúng tôi. Chúng tôi chỉ sử dụng mùa xuân cho những thứ phức tạp như các bài kiểm tra DAO, nơi chúng tôi chụp các câu lệnh thực sự dựa vào cơ sở dữ liệu trong bộ nhớ. –

0

này được khá thẳng về phía trước với "Mùa xuân tinh khiết ":

def parentAppCtx = new StaticApplicationContext() 
parentAppCtx.beanFactory.registerSingleton("myBean", Mock(MyClass)) 
parentAppCtx.refresh() 
def appCtx = new ClassPathXmlApplicationContext("spring-config.xml", parentAppCtx) 

Tất nhiên giả định rằng bạn đang phân tích chính xác cấu hình Spring của mình. (Ví dụ: Nếu bạn xác định lại "myBean" trong spring-config.xml sau đó định nghĩa trong spring-config.xml sẽ được sử dụng, vì ApplicationContext là cơ bản một bản đồ và định nghĩa mới nhất đưa vào nó sẽ giành chiến thắng.)

1

Tạo mocks bên ngoài của một đặc tả lớp có thể kể từ Spock 1.1 với DetachedMockFactorySpockMockFactoryBean. spock không gian tên cho cấu hình dựa trên XML cũng được hỗ trợ. Bạn có thể tìm các ví dụ sử dụng in the documentation.

Một thử nghiệm mùa xuân sử dụng cấu hình dựa trên nền Java và DetachedMockFactory trông như thế này:

@ContextConfiguration(classes = [TestConfig, DiceConfig]) 
class DiceSpec extends Specification { 
    @Autowired 
    private RandomNumberGenerator randomNumberGenerator 

    @Subject 
    @Autowired 
    private Dice dice 

    def "uses the random number generator to generate results"() { 
     when: 
      dice.roll() 

     then: 
      1 * randomNumberGenerator.randomInt(6) 
    } 

    static class TestConfig { 
     private final mockFactory = new DetachedMockFactory() 

     @Bean 
     RandomNumberGenerator randomNumberGenerator() { 
      mockFactory.Mock(RandomNumberGenerator) 
     } 
    } 
} 

@Configuration 
class DiceConfig { 
    @Bean 
    Dice dice(RandomNumberGenerator randomNumberGenerator) { 
     new Dice(randomNumberGenerator) 
    } 
} 

Và dựa trên XML cấu hình sẽ trông như thế này:

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:spock="http://www.spockframework.org/spring" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd 
      http://www.spockframework.org/spring http://www.spockframework.org/spring/spock.xsd"> 
    <spock:mock id="randomNumberGenerator" class="RandomNumberGenerator"/> 
</beans> 

Hãy chắc chắn để bao gồm các spock-spring phụ thuộc:

testCompile group: 'org.spockframework', name: 'spock-spring', version: '1.1-groovy-2.4-rc-3' 
Các vấn đề liên quan