2012-05-23 28 views
18

İlk defa çağrıldığında ikinci kez farklı bir değer döndüren bir yöntemle nasıl dalga geçebileceğimi araştırıyorum. zaman. Örneğin, böyle bir şey:RhinoMocks - dönüş değeri değiştiğinde (aynı parametreyi geçtiğinde bile)

public interface IApplicationLifetime 
{ 
    int SecondsSinceStarted {get;} 
} 

[Test] 
public void Expected_mock_behaviour() 
{ 
    IApplicationLifetime mock = MockRepository.GenerateMock<IApplicationLifetime>(); 

    mock.Expect(m=>m.SecondsSinceStarted).Return(1).Repeat.Once(); 
    mock.Expect(m=>m.SecondsSinceStarted).Return(2).Repeat.Once(); 

    Assert.AreEqual(1, mock.SecondsSinceStarted); 
    Assert.AreEqual(2, mock.SecondsSinceStarted); 
} 

Bunu mümkün kılan bir şey var mı? Bir devlet makinesini uygulayan alıcıya bir alt uygulamanın yanı sıra?

Şerefe dostlar,

Alex

+0

Sipariş edilen ve sırasız alaylara bakın: http://ayende.com/wiki/Rhino%20Mocks%20Ordered%20and%20Unordered.ashx – Maciej

+2

Sağladığınız kodun nesi yanlış? 'Repeat.Once()' –

+0

@lazyberezovsky çalışmalı m.SecondsSinceStarted için ilk çağrı 2, beklendiği gibi 1 değil, – AlexC

cevap

28

Sen .WhenCalled yöntemle dönüş değerleri müdahale edebilir.

int invocationsCounter = 1; 
const int IgnoredReturnValue = 10; 
mock.Expect(m => m.SecondsSinceLifetime) 
    .WhenCalled(mi => mi.ReturnValue = invocationsCounter++) 
    .Return(IgnoredReturnValue); 

Assert.That(mock.SecondsSinceLifetime, Is.EqualTo(1)); 
Assert.That(mock.SecondsSinceLifetime, Is.EqualTo(2)); 

Düzenleme:: ReturnValue yöntem çağırma gelen değiştirilirse yine .Return yöntemi ile değer sağlamak gerektiğini, ancak Rhino basitçe göz ardı eder Not

biraz daha etrafında kazı yapan görülüyor ki .Repeat.Once() aslında bu durumda çalışır ve aynı sonucu elde etmek için kullanılabilir:

mock.Expect(m => m.SecondsSinceStarted).Return(1).Repeat.Once(); 
mock.Expect(m => m.SecondsSinceStarted).Return(2).Repeat.Once(); 
mock.Expect(m => m.SecondsSinceStarted).Return(3).Repeat.Once(); 

Ardışık çağrılar için 1, 2, 3 döndürür.

+0

Anladığım gibi, sıralı sayılar dışında bir şey için dizi oluşturmak ve indeks ile değerleri döndürmek gerekir? –

+0

Bu yöntemin çalıştığını kabul ediyorum, ancak bu, kaçınmaya çalıştığım bahsettiğim bir devlet makinesini uygulamakla aynı şeydir (örn.eğer ikinci aramaya 11 dönmek istediysem, o zaman "if (invocationsCounter == 1) 1" gibi bir şey yapmam gerekecek, eğer (invocationsCounter == 2) 11; Bir devlet makinesine çok benziyor. – AlexC

+0

Re: Düzenlemenizi. Bu, kullandığım ve kullandığınız RhinoMocks sürümünde değiştirilen bazı işlevler olup olmadığından emin değil, ancak özgün sorumdaki testi çalıştırdım ve başarısız olduğunu söyleyebilirim (örneğin, ilk çağrı SecondsSinceStarted döndürür 2). Çalıştığını bulduğunuz yere bir bağlantınız var mı? – AlexC

0

Yöntemin ne zaman döndüğü belirleyicidir? Eğer öyleyse, zaman pasajını soyutlamaya çalışacağım, böylece testlerinizde doğrudan kontrolünüz var.

GetElapsedTime() adlı bir üye ile ITimeProvider adlı bir arabirim gibi bir şey yapın ve sonra uygulamanız boyunca kullanmak üzere varsayılan bir uygulama oluşturun.

Daha sonra, sınandığınız zaman, alaylı bir ITimeProvider'ı iletin; böylece, uygulamanız tarafından algılanan öğenin zaman geçmesini denetlersiniz.

+0

Gerçekten, zaman meselesi, tam olarak ne denediğini açıklamaya çalışmak yerine, kullanışlı bir örnekti. Öyle olsa bile, GetElapsedTime() yöntemine sahip bir ITimeProvider ile uğraşmak istesem de, GetElapsedTime() adında iki kez denen bir birim testi yazmak istediğimde sorun devam edecekti ve ITimeProvider'ın farklı bir geri dönmesini istedim. her arama için zaman. – AlexC

+0

ITimeProvider'ın bir mülk bağımlılığı olabileceğini düşünüyor musunuz? Böylece her aramadan önce yeni alaylar enjekte edebilmek mümkün mü? Öyle olsa bile, onunla uğraşma zamanınız olmasa bile, cevabım muhtemelen değersizdir ... – theMothaShip

+0

Benim sorum, RhinoMocks'un oluşturulmuş mocks/stubs ile bu tür bir etkileşimi destekleyip desteklemediğiyle ve onun etrafında nasıl çalışacağım konusunda daha az mıydı? desteklenmemelidir. Yine de teşekkürler. – AlexC

5

Basitçe ikinci çağrı sırasında ilk arama sırasında 1 ve 2 dönecektir

mock.Expect(m=>m.SecondsSinceStarted).Return(1).Repeat.Once(); 
mock.Expect(m=>m.SecondsSinceStarted).Return(2).Repeat.Once(); 

Bu

kullanın. En azından, RhinoMocks 3.6.0.0

+0

Bu kesinlikle testin – AlexC

+0

üzerinde çalıştığını gördüğümle çakışıyor Kabul edilen cevapta da belirtildiği gibi, bu doğru, testim sadece adım attığımda ve bir şeyi yanlışlıkla değerlendirirken başarısız oldu. Upvoted. – AlexC