2009-03-10 32 views
18

Tôi có thể thay đổi hành vi của một cuống trong thời gian chạy không? Một cái gì đó như:Làm thế nào để thay đổi hành vi của cuống?

public interface IFoo { string GetBar(); } 
    [TestMethod] 
    public void TestRhino() 
    { 
     var fi = MockRepository.GenerateStub<IFoo>(); 
     fi.Stub(x => x.GetBar()).Return("A"); 
     Assert.AreEqual("A", fi.GetBar()); 
     fi.Stub(x => x.GetBar()).Return("B"); 
     Assert.AreEqual("B", fi.GetBar()); // Currently fails here 
    } 

mã ví dụ của tôi vẫn không trong dòng nhất định, fi.GetBar() vẫn trả "A".

Hoặc có một mẹo khác để mô hình hóa các ca có hành vi thay đổi theo thời gian không? Tôi không muốn sử dụng fi.Stub(...).Do(...).

Ah, có lẽ tôi chỉ cần bản cứng của sổ tay tinh xảo để ai đó đánh vào đầu tôi bằng nó. Có vẻ như nó thực sự rõ ràng, nhưng tôi không thể tìm thấy nó.

+0

Hãy thử 'fi.Stub (x => x.GetBar()) Trả về (" A ") Lặp lại.Once();' và 'fi.Stub (x => x.GetBar()). "B"). Repeat.Once(); ' –

Trả lời

26

CẢNH BÁO

Thay đổi hành vi của cuống là một mùi mã!

Nó thường chỉ ra rằng các bài kiểm tra đơn vị của bạn quá phức tạp, khó hiểu và dễ vỡ, dễ dàng phá vỡ các thay đổi chính xác của lớp đang thi.

Check-out:

  • [xUnit thử nghiệm Patterns] [1]
  • [The Art Of đơn vị kiểm tra] [2]

Vì vậy, đề nghị: chỉ sử dụng giải pháp này nếu bạn không thể tránh nó. Trong mắt tôi, bài viết này nằm trên những lời khuyên xấu - tuy nhiên có những tình huống hiếm hoi mà bạn thực sự cần đến nó.


Ah, tôi đã tự tìm ra. Rhino hỗ trợ chế độ ghi lại/phát lại. Trong khi cú pháp AAA luôn giữ các đối tượng trong chế độ phát lại, chúng ta có thể chuyển sang ghi và quay lại để phát lại chỉ để xóa hành vi của sơ khai.

Có vẻ một chút hackish, tuy nhiên ...

public interface IFoo { string GetBar(); } 
    [TestMethod] 
    public void TestRhino() 
    { 
     var fi = MockRepository.GenerateStub<IFoo>(); 
     fi.Stub(x => x.GetBar()).Return("A"); 
     Assert.AreEqual("A", fi.GetBar()); 

     // Switch to record to clear behaviour and then back to replay 
     fi.BackToRecord(BackToRecordOptions.All); 
     fi.Replay(); 

     fi.Stub(x => x.GetBar()).Return("B"); 
     Assert.AreEqual("B", fi.GetBar()); 
    } 

Cập nhật:

tôi sẽ sử dụng này trong tương lai, vì vậy điều trông đẹp hơn một chút:

internal static class MockExtension { 
    public static void ClearBehavior<T>(this T fi) 
    { 
     // Switch back to record and then to replay - that 
     // clears all behaviour and we can program new behavior. 
     // Record/Replay do not occur otherwise in our tests, that another method of 
     // using Rhino Mocks. 

     fi.BackToRecord(BackToRecordOptions.All); 
     fi.Replay(); 
    } 
} 
+0

Nếu bạn muốn sử dụng thuật ngữ là n ative để Rhino Mocks, làm cho nó ClearExpectations –

+1

@Richard: Hành vi được thêm vào với '.Stub' không đặt kỳ vọng. Bạn đang nghĩ đến Hành vi được thêm vào với '.Expect'. –

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