2011-08-09 7 views
20

Używam RhinoMocks, próbuję rozszerzyć wartość gettera właściwości. Właściwość jest zdefiniowana jako część interfejsu z dostępem tylko do gettera.Stubbingowanie właściwości za pomocą Rhino Mocks

Jednak pojawia się błąd "Nieprawidłowe połączenie, ostatnie połączenie zostało użyte lub nie zostało wykonane żadne połączenie (upewnij się, że wywołujesz metodę wirtualną (C#)/Overridable (VB))." Rozumiem, że może to oznaczać, że posiadana przeze mnie nieruchomość nie jest wirtualna; Jednak jest to część interfejsu i nie jestem pewien, czy to jest powód, dla którego dostaję ten błąd ..

Poniżej znajduje się szkielet kodu. Jeśli odkomentuję wiersz, który mówi "stubRepository.Stub (x => x.StoreDeviceID) .PropertyBehavior();", wtedy pojawia się nowy błąd "Właściwość musi być odczytana/zapisana". Szukałem na SO i znalazłem stronę this. Ale proponowane rozwiązanie mi nie pomaga. jakieś pomysły?

public interface IStore { 
     string StoreDeviceID {get;} 
     //other methods 
    } 

    public static class Store { 
     private IStore Repository; 

     public void SetRepository(IStore rep){ 
      Repository = rep; 
     } 

     public StoredeviceID { 
      get{ 
       return Repository.StoreDeviceID; 
      } 
     } 

     //other methods 
    } 

    public class TestClass { 
     [Test] 
     public void TestDeviceID() { 
      var stubRepository = 
       MockRepository.GenerateStub<IStore>(); 
      Store.SetRepository(stubRepository); 

      //stubRepository.Stub(x => x.StoreDeviceID).PropertyBehavior(); 
      SetupResult.For(stubRepository.StoreDeviceID).Return("test"); 

      Assert.AreSame(Store.StoreDeviceID, "test"); 
     } 
    } 

Odpowiedz

28

Ponieważ jest to właściwość tylko do odczytu, trzeba powiedzieć:

stubRepository.Stub(x => x.StoreDeviceID).Return("test"); 

Normalnie w króćce, właściwości są używane jak normalne właściwości C#. Więc dla właściwości nie tylko do odczytu, można by powiedzieć: stubRepository.someProperty = "test";

Należy również pamiętać, że jeśli chcesz założyć metodę zachowywać się w określony sposób, niezależnie od tego, czy jest to mock lub skrótową, byś zawsze powiedzieć:

stubRepository.Stub(x => x.someMethod()).Return("foo"); 

Pamiętaj, że odcinki są tam dostarczyć swoje testy jednostkowe z ich niezbędnymi zależnościami, ale są nie tam uruchomić na weryfikacje; po to są mocks.

Użyj kodu pośredniczącego, aby uzyskać zależność, która zachowuje się w określony sposób. Użyj makiety, jeśli chcesz sprawdzić, czy pewna zależność została poprawnie powiązana.

Z (wybitny) Rhino Wiki:

A mock is an object that we can set expectations on, and which will verify that the expected actions have indeed occurred. A stub is an object that you use in order to pass to the code under test. You can setup expectations on it, so it would act in certain ways, but those expectations will never be verified. A stub's properties will automatically behave like normal properties, and you can't set expectations on them.

If you want to verify the behavior of the code under test, you will use a mock with the appropriate expectation, and verify that. If you want just to pass a value that may need to act in a certain way, but isn't the focus of this test, you will use a stub.

IMPORTANT: A stub will never cause a test to fail.

+0

@ Adam, Ponieważ właściwość jest tylko do odczytu, nie mogę jej ustawić. Jednak fragment kodu, który podałeś pod tym adresem, działa doskonale. Silly me, wypróbowałem wszystkie inne opcje oprócz tego :) – Santhosh

+0

StoreDeviceID nie ma ustawiacza, więc twoja pierwsza instrukcja 'stubRepository.StoreDeviceID =" test ";' nie zadziała. –

+0

Ahh - przepraszam. Zaktualizuję odpowiedź - cieszę się, że udało ci się. –

4

można wykonać następujące czynności z odgałęzienie:

stubRepository.Stub(x => x.StoreDeviceID).Return("test"); 

Spowoduje to powrót "test" dla każdego wywołania getter StoreDeviceID użytkownika.