2012-11-30 47 views
8

Tôi có cuộc gọi dao.create() mà tôi muốn giả lập khi thử nghiệm một phương thức. Nhưng tôi thiếu một cái gì đó như tôi vẫn nhận được NPE. Có gì sai ở đây?Làm thế nào để chế biến một biến dao riêng?

class MyService { 
    @Inject 
    private Dao dao; 

    public void myMethod() { 
     //.. 
     dao.create(object); 
     // 
    } 
} 

Làm cách nào tôi có thể thực hiện cuộc gọi dao.create()?

@RunWith(PowerMockRunner.class) 
@PrepareForTest(DAO.class) 
public void MyServiceTest { 

    @Test 
    public void testMyMethod() { 
     PowerMockito.mock(DAO.class); 

     MyService service = new MyService(); 
     service.myMethod(); //NPE for dao.create() 
    } 
} 
+0

Lớp học "DAO" hoặc "Dao"? – fgb

+0

Một số giải pháp tốt phụ thuộc vào khung tiêm phụ thuộc mà bạn đang sử dụng. Xin vui lòng thêm một thẻ thích hợp (guice, spring, ...) –

Trả lời

5

Bạn không tiêm DAO. Với mockito, bạn có thể thay đổi lớp thử nghiệm của mình để sử dụng @InjectMocks và sử dụng nhân vật mockito.

@RunWith(MockitoJUnitRunner.class) 
public void MyServiceTest { 
    @Mock 
    private Dao dao; 
    @InjectMocks 
    private MyService myService; 
    ... 
} 

Bạn có thể đọc thêm về InjectMocks tại Inject Mocks API

đơn giản hơn cách đang thay đổi của bạn để tiêm tiêm bởi constructor. Ví dụ: bạn sẽ thay đổi MyService thành

class MyService { 
    ... 
    private final Dao dao; 

    @Inject 
    public MyService(Dao dao) { 
     this.dao = dao; 
    } 
    ... 
} 

sau đó thử nghiệm của bạn có thể đơn giản vượt qua DAO giả lập trong khi thiết lập.

... 
@Mock 
private Dao dao; 

@Before 
public void setUp() { 
    this.dao = mock(Dao.class); 
    this.service = new MyService(dao); 
} 
... 

bây giờ bạn có thể sử dụng để kiểm tra xem verifycreate được gọi, như:

... 
    verify(dao).create(argThat(isExpectedObjectBeingCreated(object))); 
} 

private Matcher<?> isExpectedObjectBeingCreated(Object object) { ... } 

Sử dụng tiêm bởi nhà xây dựng sẽ cho phép phụ thuộc của bạn rõ ràng hơn để các nhà phát triển khác và nó sẽ giúp khi tạo kiểm tra :)

+0

Xin lỗi về người nghèo tiếng anh: P –

+1

bạn tiếng anh không phải là xấu và nó giúp tôi rất nhiều. cảm ơn! – membersound

1

Bạn vẫn cần đặt trường dao bằng mô hình của mình. Bạn có thể sử dụng sự phản chiếu này.

1

Bạn cần phải tiêm/đặt DAO đối tượng giả trong lớp dịch vụ của bạn.

Nếu nó là một dự án mùa xuân dựa, bạn có thể có một cái nhìn @ Xuân Junit testrunner

0

Nếu bạn sử dụng new MyService() người Dao không bao giờ được tiêm. Đối với người Dao được tiêm, bạn cần tải MyService qua số ApplicationContext (Mùa xuân) hoặc Injector (Guice). Giống như bạn sẽ làm trong ứng dụng bình thường của bạn.

0

Như những người khác đã nói, bạn cần phải đặt trường dao trong lớp MyService của bạn theo một cách nào đó. Tôi không chắc chắn cơ chế cho phép một Á hậu hỗn hợp trong thử nghiệm của bạn sử dụng cả Powermock và một khung công tác DI (giả sử Powermock là bắt buộc), nhưng miễn là bạn đã sử dụng PowerMock (vì lý do không rõ ràng trong ví dụ đã cho) , bạn có thể tận dụng bản thân của lớp Whitebox để đặt dao thủ công hơn.

public void testMyMethod() { 
    Dao dao = mock(Dao.class) 
    doNothing().when(dao).create(anyObject())); //assuming no return val for dao.create() 

    MyService service = new MyService(); 
    Whitebox.setInternalState(service, "dao", dao); 

    service.myMethod(); 
} 
Các vấn đề liên quan