2010-06-22 30 views
14

Tôi nhận được đối tượng Moq để trả về các giá trị khác nhau cho các cuộc gọi liên tiếp đến một phương thức. Điều này được thực hiện theo phương pháp tiện ích mở rộng này:Trả lại các kết quả khác nhau hoặc ném ngoại lệ từ các cuộc gọi liên tiếp đến Moq Mock

public static void ReturnsInOrder<T, TResult>(this ISetup<T, TResult> setup, params TResult[] results) where T : class 
{ 
    setup.Returns(new Queue<TResult>(results).Dequeue); 
} 

Bây giờ tôi muốn một trong các cuộc gọi để ném ngoại lệ trong khi những người khác trả lại điều gì đó. Có ai làm điều này trước khi?

Nếu tôi làm điều này

mock.Setup(m => m.SomeMethod()) 
    .Throws(new Exception()); 
mock.Setup(m => m.SomeMethod()) 
    .Returns("ok"); 

thì các thiết lập đầu tiên được ghi đè và chỉ thiết lập thứ hai vẫn còn.

Trả lời

9

Tôi đã sử dụng chuỗi gọi lại trong khi phát triển proxy thử lại.

var src = new Mock<ITest>(); 
src.Setup(s => s.RaiseError()).Callback(() => 
src.Setup(s => s.RaiseError())).Throws<Exception>(); 

const int retryCount = 1; 
var proxy = RetryProxy.MakeFor(src.Object, retryCount); 

proxy.RaiseError(); 
src.Verify(s => s.RaiseError(), Times.Exactly(retryCount+1)); 
+0

(khá phức tạp) Giải pháp này là không cần thiết nữa kể từ Moq đã hỗ trợ cho phương pháp SetupSequence. Xem câu trả lời của tôi bên dưới để biết ví dụ. – nashwan

10

Ngày nay Moq (phiên bản 4+) hỗ trợ điều này thông qua phương thức SetupSequence. Xem this post để được giới thiệu.

+1

Nhưng trong bản phát hành chính thức, nó không cho phép trả lại một giá trị từ phương thức giả sau khi ném một ngoại lệ (vẫn có thể thực hiện việc này theo thứ tự ngược lại) - https://code.google.com/p/moq/issues/detail? id = 319 – Marek

0

Sử dụng SetupSequence(...) trên đối tượng giả.

Ví dụ sau đây sẽ ném ngoại lệ về cuộc gọi đầu tiên và trở someResponse trên cuộc gọi thứ hai:

myService.SetupSequence(s => s.PlaceOrder()) 
    .Throws(new Exception()) 
    .Returns(someResponse); 
+0

Throws trả về void vì vậy đơn hàng này không được phép (sử dụng Moq phiên bản 4.0) –

+0

Bạn có chắc chắn không? Tôi đang sử dụng dòng mã thực sự này và nó hoạt động tốt cho tôi. Tôi đang sử dụng phiên bản Moq 4.0.30319. Bạn có chắc là "PlaceOrder()" của bạn (hay phương pháp tương đương) thực sự đang được gọi? – nashwan

+0

Tôi đang sử dụng Moq.WithoutCastle -Version 4.0.10827.2 và mã sẽ không biên dịch. Có lẽ nó là một hạn chế của Moq.WithoutCastle. –

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