2012-05-14 25 views
9

Essence:Kết hợp JBehave với SpringJUnit4ClassRunner để cho phép rollback giao dịch

Làm thế nào tôi có thể tự động rollback tôi ngủ đông giao dịch trong một JUnit Chạy thử với JBehave?

Vấn đề có vẻ là JBehave muốn SpringAnnotatedEmbedderRunner nhưng chú thích thử nghiệm là @Transactional yêu cầu SpringJUnit4ClassRunner.

Tôi đã cố gắng tìm một số tài liệu về cách triển khai hoặc khôi phục bằng SpringAnnotatedEmbedderRunner hoặc để thực hiện công việc JBehave bằng cách sử dụng SpringJUnit4ClassRunner nhưng tôi không thể làm việc.

Có ai có thiết lập (tốt hơn là đơn giản) chạy các kho lưu trữ JBehave với Spring và Hibernate và tự động khôi phục giao dịch không?



infos thêm về thiết lập của tôi cho đến nay:

Working JBehave với mùa xuân - nhưng không phải với tính năng tự động rollback:

@RunWith(SpringAnnotatedEmbedderRunner.class) 
@Configure(parameterConverters = ParameterConverters.EnumConverter.class) 
@UsingEmbedder(embedder = Embedder.class, generateViewAfterStories = true, ignoreFailureInStories = false, ignoreFailureInView = false) 
@UsingSpring(resources = { "file:src/main/webapp/WEB-INF/test-context.xml" }) 
@UsingSteps 
@Transactional // << won't work 
@TransactionConfiguration(...) // << won't work 
// both require the SpringJUnit4ClassRunner 

public class DwStoryTests extends JUnitStories { 

    protected List<String> storyPaths() { 

     String searchInDirectory = CodeLocations.codeLocationFromPath("src/test/resources").getFile(); 
     return new StoryFinder().findPaths(searchInDirectory, Arrays.asList("**/*.story"), null); 
    } 

} 

Trong các bước thử nghiệm của tôi, tôi có thể @Inject mọi thứ độc đáo:

@Component 
@Transactional // << won't work 
public class PersonServiceSteps extends AbstractSmockServerTest { 

    @Inject 
    private DatabaseSetupHelper databaseSetupHelper; 

    @Inject 
    private PersonProvider personProvider; 

    @Given("a database in default state") 
    public void setupDatabase() throws SecurityException { 
     databaseSetupHelper.createTypes(); 
     databaseSetupHelper.createPermission(); 
    } 

    @When("the service $service is called with message $message") 
    public void callServiceWithMessage(String service, String message) { 
     sendRequestTo("/personService", withMessage("requestPersonSave.xml")).andExpect(noFault()); 
    } 

    @Then("there should be a new person in the database") 
    public void assertNewPersonInDatabase() { 
     Assert.assertEquals("Service did not save person: ", personProvider.count(), 1); 
    } 

(có, các phương thức DatabaseSetupHelper là tất cả giao dịch)

PersonProvider cơ bản là bao bọc xung quanh org.springframework.data.jpa.repository.support.SimpleJpaRepository. Vì vậy, có quyền truy cập vào thực thểManager nhưng kiểm soát các giao dịch (với bắt đầu/rollback) đã không làm việc, tôi đoán vì tất cả các @Transactional s được thực hiện dưới mui xe bên trong lớp trợ giúp đó.

Tôi cũng đọc rằng JBehave chạy trong một ngữ cảnh khác? Phiên? gây mất kiểm soát đối với giao dịch bắt đầu bằng thử nghiệm? Khá thứ khó hiểu ..


chỉnh sửa:

Editet trên rephrasing bài viết để phản ánh kiến ​​thức hiện tại của tôi và rút ngắn toàn bộ điều để các câu hỏi trở nên rõ ràng hơn và các thiết lập ít obstrusive.

Trả lời

2

Tôi nghĩ bạn có thể bỏ qua SpringAnnotatedEmbedderRunner và cung cấp cấu hình cần thiết cho chính JBehave.Ví dụ thay vì

@UsingEmbedder(embedder = Embedder.class, generateViewAfterStories = true, ignoreFailureInStories = false, ignoreFailureInView = false) 

bạn có thể làm

configuredEmbedder() 
.embedderControls() 
.doGenerateViewAfterStories(true) 
.doIgnoreFailureInStories(false) 
.doIgnoreFailureInView(false); 

Bên cạnh đó: tại sao bạn muốn rollback giao dịch? Thông thường bạn đang sử dụng JBehave để kiểm tra chấp nhận, chạy trong môi trường giống như sản xuất. Ví dụ bạn đầu tiên thiết lập một số dữ liệu trong cơ sở dữ liệu, truy cập nó thông qua Browser/Selenium và kiểm tra kết quả. Để làm việc đó, giao dịch DB phải được thực hiện. Bạn có cần dọn dẹp thủ công sau khi thử nghiệm của mình, bạn có thể làm gì trong các phương thức chú thích @AfterStories hoặc @AfterScenario.

+0

Hm .. Nghe có vẻ như tôi có thể thử. Cảm ơn, sẽ kiểm tra nó ra vào tuần tới. Các kiểm tra chấp nhận của chúng tôi sẽ không chạy với ứng dụng được triển khai, chúng tôi dành riêng cho các thử nghiệm từ đầu đến cuối. Kiểm tra chấp nhận của chúng tôi sẽ chạy với mô hình miền trực tiếp bao gồm cơ sở dữ liệu sạch mà chúng tôi muốn tự động trả lại. – Pete

1

Tôi không quen với JBehave, nhưng có vẻ như bạn đang tìm kiếm chú thích này.

@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true). 

Bạn cũng có thể đặt defaultRollback thành true trong testContext của mình.

+0

Không có điều đó sẽ không hoạt động. Đó là chú thích 'SpringJUnit4ClassRunner' sẽ bị bỏ qua bởi' SpringAnnotatedEmbedderRunner' của JBehave. – Pete

1

Tôi đã làm cho nó hoạt động bằng cách kiểm soát phạm vi giao dịch theo cách thủ công, cuộn lại sau mỗi trường hợp. Chỉ cần làm theo hướng dẫn chính thức làm thế nào để sử dụng Spring với JBehave và sau đó làm các trick như hình dưới đây.

@Component 
public class MySteps 
{ 
    @Autowired 
    MyDao myDao; 

    @Autowired 
    PlatformTransactionManager transactionManager; 

    TransactionStatus transaction; 

    @BeforeScenario 
    public void beforeScenario() { 
     transaction = transactionManager.getTransaction(new DefaultTransactionDefinition()); 
    } 

    @AfterScenario 
    public void afterScenario() { 
     if (transaction != null) 
      transactionManager.rollback(transaction); 
    } 

    @Given("...") 
    public void persistSomething() { 
     myDao.persist(new Foo()); 
    } 
} 
Các vấn đề liên quan