2012-09-14 28 views
5

Tôi đang cố gắng viết một bài kiểm tra đơn vị cần xác nhận nếu phương thức được gọi hay không. Tôi đang sử dụng JUnit, Mockito và PowerMock.Cách xác minh xem phương thức có được gọi là Hệ thống đang được kiểm tra hay không (không phải là mô phỏng)

 
public class Invoice 
{ 

    protected void createInvoice() 
    { 
    // random stuff here 
    markInvoiceAsBilled("57"); 
    } 

    protected void markInvoiceAsBilled(String code) 
    { 
    // marked as billed 
    } 
} 

Vì vậy, hệ thống của tôi đang thử nghiệm là Invoice. Tôi đang chạy thử nghiệm này:

 
    public class InvoiceTest 
    { 
    @Test 
    public void testInvoiceMarkedAsBilled() 
    { 
     Invoice sut = new Invoice(); 
     Invoice sutSpy = spy(sut); 

     sut.createInvoice(); 

     // I want to verify that markInvoiceAsBilled() was called 
    } 
    } 

Ví dụ này chỉ là một ví dụ về những gì các mã thực tế trông giống như ....

Vấn đề của tôi là Mockito nói rằng bạn chỉ có thể xác minh nếu một phương pháp được gọi là trên một đối tượng giả lập ... nhưng tôi không muốn chế nhạo đối tượng này, vì nó là đối tượng của tôi đang được thử nghiệm. Tôi biết rằng bạn có thể theo dõi đối tượng bạn đang thử nghiệm, vì vậy, đây là những gì tôi đã thử:

 

    verify(sutSpy).markInvoiceAsBilled("57"); 

Là những gì tôi đang cố gắng không thể? Hay tôi chỉ đi sai đường?

Cảm ơn mọi người :)

Trả lời

5

Tôi không chắc liệu những gì bạn đang cố gắng làm là cách tốt nhất để làm mọi thứ.

tôi sẽ không liên quan đến bản thân mình với xác minh rằng Invoice.createInvoice() gọi là một nội bộ, phương pháp riêng markInvoiceAsBilled() - thay vì kiểm tra rằng gọi createInvoice() thay đổi trạng thái của đối tượng Invoice theo cách mà bạn mong đợi - ví dụ, rằng status tại là BILLED hoặc một cái gì đó tương tự .

Nói cách khác - không kiểm tra phương thức nào được gọi bởi createInvoice() - kiểm tra sau khi gọi phương thức này, trạng thái của đối tượng là những gì bạn mong đợi.

0

Tôi đồng ý với câu trả lời của Matt. Điều đó đang được nói, tùy thuộc vào trường hợp sử dụng và sự phức tạp của phương pháp, bạn có thể thiết kế lại đơn vị của bạn để nó có thể được kiểm tra.

Ví dụ: đối tượng của bạn trở nên phức tạp hơn nhiều, ví dụ:

public A { 
    public a() { 
    b(); 
    c(); 
    } 

    public b() { /** hairy code, many branches to test */ } 
    public c() { /** hairy code, many branches to test */ } 
} 

Bao gồm b với các bài kiểm tra và c với các bài kiểm tra là thẳng về phía trước, nhưng bao gồm có vẻ rắc rối vì bạn phụ thuộc vào phương pháp b và c.

Xem xét thay vì thiết kế này

public A { 
    private final Dep mDep; 

    public a() { 
    mDep.b(); 
    mDep.c(); 
    } 

    public b() { 
    mDep.b(); 
    } 

    public c() { 
    mDep.c(); 
    } 

    // dependency abstraction we create to help test 
    static class Dep { 
    public b() { /** hairy code, many branches to test */ } 
    public c() { /** hairy code, many branches to test */ } 
    } 
} 

Bây giờ, thử nghiệm A.a, A.bA.c chỉ đòi hỏi bạn phải xác minh của bạn mDep được gọi là (trong bất cứ điều gì khác phương pháp nào). Riêng biệt, bạn thử nghiệm các phương pháp A.Dep.bA.Dep.c.

Các vấn đề liên quan