2011-07-20 27 views
5

Với hệ thống phân cấp lớp giống như sau:Làm thế nào để ngăn chặn siêu lớp khỏi bị chế nhạo bởi jmockit?

public class Vehicle { 

    private String name; 

    public Vehicle(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 

} 


public class Car extends Vehicle { 

    public Car(String name) { 
     super(name); 
    } 

    public String drive() { 
     return "driving the car"; 
    } 

    public String boardBus() { 
     Bus bus = new Bus("bus to cut off"); 

     return bus.board(); 
    } 

} 

public class Bus extends Vehicle { 

    public Bus(String name) { 
     super(name); 
    } 

    public String board() { 
     return "boarding the bus"; 
    } 

} 

Tôi đang cố gắng kiểm tra lớp Xe. Tuy nhiên, Car cũng sẽ sử dụng Bus. Vì vậy, trong bài kiểm tra của tôi, tôi đang cố gắng chế nhạo Bus. Mã thử nghiệm của tôi trông giống như sau:

import static org.junit.Assert.assertEquals; 
import mockit.Mocked; 
import mockit.NonStrictExpectations; 

import org.junit.Test; 

public class CarTest { 

    @Test 
    public void testCar() { 
     final String name = "I am a car"; 
     final Car car = new Car(name); 

     new NonStrictExpectations() { 
      @Mocked Bus bus; 

      { 
       bus.board(); result = "test bus boarding"; 
      } 
     }; 

     assertEquals("I am a car", car.getName()); 
    } 

} 

Xác nhận không thành công vì car.getName() trả về giá trị rỗng.

Bằng cách chèn System.out.println trong các nhà thầu cho Xe hơi, Xe hơi và Xe buýt, tôi nghi ngờ rằng xe "thực" được nạp bởi new Car(name) sau đó được thay thế bằng Xe mô phỏng khi @Mocked Bus bus được thực thi.

Có cách nào để jmockit bảo toàn Xe thật được "khởi tạo" khi Xe được chế tạo không?

Trả lời

1

tôi thấy hai giải pháp:

@Test 
public void boardBus_usingInstanceSpecificMockingForNewedInstances() 
{ 
    new Expectations() { 
     @Capturing @Injectable Bus bus; 

     { 
      bus.board(); result = "mocked"; 
     } 
    }; 

    String result = new Car("myCar").boardBus(); 
    assertEquals("mocked", result); 
} 

@Test 
public void boardBus_usingPartialMocking() 
{ 
    final Bus bus = new Bus(""); 
    new Expectations(bus) {{ bus.board(); result = "mocked"; }}; 

    String result = new Car("myCar").boardBus(); 
    assertEquals("mocked", result); 
} 
+1

Cả hai đều hoạt động. Tôi đã quyết định sử dụng kỹ thuật '@ Captureuring'. Cảm ơn đã giúp đỡ! – rdguam

0

Không có xe "được liên kết" với Ô tô - Xe hơi là Xe số. Hiệp hội và thừa kế không giống nhau. Do đó không thể có một chiếc xe với một chiếc xe "chế giễu" - câu này là vô nghĩa khi Car extends Vehicle.

Bạn có chắc chắn không có lỗi (legit) trong bộ khởi tạo của ô tô hoặc getName()? Mã cho các phương thức này trông như thế nào?

+0

tôi sẽ cập nhật với các mã cho ba lớp. – rdguam

+1

và điều gì sẽ xảy ra nếu bạn xóa phần tử 'New NonStrictExpectations() {@Mocked ...' khỏi thử nghiệm đơn vị, chỉ cần kiểm tra hoàn toàn phương thức khởi tạo Ô tô và 'getName()'? Có một thử nghiệm mà không có bất kỳ vượt qua mocking? Cái gì đó không thêm ở đây. –

+0

Có, kiểm tra sẽ trôi qua nếu tôi nhận xét 'new NonStrictExpectations() {...};'. – rdguam

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