2013-04-04 31 views
5

Tôi có một thiết lập lớp theo cách sau đây:Microsoft Fakes có hỗ trợ các phương pháp trừu tượng trên shim không?

public abstract FooClass { 
    public FooClass() { 
     // init stuff; 
    } 

    public void RandomMethod() { 
     // do stuff; 
    } 

    public abstract WhatIWantToShim(); 
} 

Những gì tôi muốn làm là thiết lập các WhatIWantToShim trên ShimFooClass như vậy:

ShimFooClass.AllInstances.WhatIWantToShim =() => Boo(); 

tôi có thể thiết RandomMethod tốt,

ShimFooClass.AllInstances.RandomMethod =() => CalculatePi(); 

Tuy nhiên, có vẻ như ShimFooClass đã tạo không tạo thuộc tính WhatIWantToShim trên thuộc tính AllInstances của ShimFooClass.

Tôi đã xem http://msdn.microsoft.com/en-us/library/hh549176.aspx#bkmk_shim_basics nhưng tôi không thấy bất kỳ điều gì về phương pháp trừu tượng. Điều duy nhất tôi thấy được tham chiếu không được hỗ trợ là finalizers. Bất kỳ ai biết điều gì đang xảy ra ở đây và nếu kịch bản này được hỗ trợ?

+0

Bạn có thể tạo phương thức đặt thuộc tính không? – RedJandal

+0

Không theo bạn, không có thuộc tính nào cho phương thức trừu tượng được tạo trên lớp shim. Đó là vấn đề. –

Trả lời

4

Ahhh .... con số thấp

giao diện và phương pháp trừu tượng. Sơ khai cung cấp việc triển khai các giao diện và các phương thức trừu tượng có thể được sử dụng trong thử nghiệm. Miếng chêm không thể giao diện dụng cụ và phương pháp trừu tượng, bởi vì chúng không có thân phương pháp.

http://msdn.microsoft.com/en-us/library/hh549175(v=vs.110).aspx

Cập nhật: những gì có thể được thực hiện mặc dù được stubbing các shim.

using (ShimsContext.Create()) 
{ 
    bool wasAbstractMethodCalled = false; 
    var targetStub = new StubFooClass() 
    { 
     WhatIWantToShim01 =() => wasAbstractMethodCalled = true 
    }; 
    var targetShim = new ShimFooClass(targetStub); 
    targetShim.AllInstances.RandomMethod =() => CalculatePi(); 
    FooClass target = targetShim.Instance; 
    target.WhatIWantToShim(); 
    Assert.IsTrue(wasAbstractMethodCalled, "The WhatIWantToShim method was not called."); 
} 

Kể từ khi shim không thể xử lý detouring phương pháp WhatIWantToShim và stub thể, chỉ cần tạo một đối tượng mới của lớp còn sơ khai và thiết lập xử lý đường vòng cho phương pháp trừu tượng. (Lưu ý: 01 được gắn thẻ ở cuối phần tử WhatIWantToShim được thêm tự động cho tôi khi Số tiền được tạo trong mã thực tế của tôi).

Sau đó, chỉ cần chuyển bản gốc đã tạo ra cho hàm tạo của lớp shim và shim đi khi cần.

0

Tôi đang trả lời ở đây vì tôi khá chắc chắn câu trả lời khác không trả lời được câu hỏi và do đó các tìm kiếm trong tương lai trả về thông tin hữu ích.

Thứ nhất, bạn không thể giao diện thân thiện. Một phương thức trừu tượng tương đương với một giao diện. Hơn nữa, không có lý do gì để.

{ 
    bool wasAbstractMethodCalled = false; 
    var targetStub = new StubFooClass() 
    { 
     WhatIWantToShim01 =() => wasAbstractMethodCalled = true 
    }; 
    ShimFooClass.AllInstances.RandomMethod = @class => targetStub.CalculatePi(); 
    targetStub.WhatIWantToShim(); 
    Assert.IsTrue(wasAbstractMethodCalled, "The WhatIWantToShim method was not called."); 
} 

Ở trên là phiên bản đơn giản của câu trả lời trước và chỉ đơn giản gọi hành động bạn vừa chỉ định. Đây có lẽ không phải là ý định của bạn.

Hãy nhớ TẠI SAO bạn shim. Bạn shim khi bạn muốn tránh những tác động của một cuộc gọi phương thức trong một phương pháp bạn đang thử nghiệm. Phương pháp trừu tượng có thể không có thân thể, và do đó không thể ảnh hưởng gì cả. Thời gian duy nhất này sẽ hữu ích là trong một lớp trẻ em, nơi shim sẽ có sẵn cho bạn ở nơi đầu tiên.

Tình huống duy nhất mà bạn có thể có vấn đề là nếu lớp thứ ba bí mật giữ một thể hiện của lớp trừu tượng và khởi tạo nó với lớp con. Bạn không thể giả mạo điều đó. Đó là, tuy nhiên, thiết kế khủng khiếp; Ví dụ nên đến từ một số phương pháp (mà bạn có thể shim) hoặc thông qua trong (Bởi vì DI là một điều tốt!) hoặc người nào khác trừu tượng là vô giá trị, và bạn cũng có thể có cá thể được khai báo là kiểu con, vì bạn không sử dụng trừu tượng theo bất kỳ cách nào.