2009-06-12 6 views
6

Kpię sobie z otoki do MSMQ. Opakowanie pozwala na utworzenie instancji obiektu, która bezpośrednio wywołuje metody statyczne klasy MessageQueue.Czy mogę uzyskać serię dobrych wyników i wyrzucony wyjątek od Moq

Chcę przetestować czytanie kolejki do wyczerpania. Aby to zrobić, chciałbym, aby wyśmiewana owijka zwróciła kilka dobrych wyników i wyrzuciła wyjątek w czwartym wywołaniu tej samej metody. Metoda nie przyjmuje żadnych parametrów i zwraca standardowy obiekt komunikatu.

Czy mogę ustawić tę serię oczekiwań dotyczących metody w Moq?

+0

+1 Ponieważ Moq jest super ;-) – toxvaerd

+0

Opowiedz mi o tym! Przez ponad rok używałem jakiegoś komercyjnego produktu, którego nazwa pozostanie tu niewidoczna, a NIENAWIDZIAŁam z drwin. Musiałem ciągle czytać i ponownie czytać dokumentację za każdym razem. Moq to taki powiew świeżego powietrza. Udało mi się go użyć za kilka minut i rzadko muszę czytać dokumentację. –

+0

Używam RhinoMocks, ale myślałem, że dam Moqowi szansę, aby zobaczyć, jak to się porównuje i rozpowszechniać moją wiedzę. Jestem teraz konwerterem - uważam, że składnia Moq jest łatwiejsza do odczytania podczas skanowania kodu. – BlackWasp

Odpowiedz

5

Tak, jest to możliwe, jeśli nie masz nic przeciwko skakaniu przez kilka mniejszych kółek. Zrobiłem to już wcześniej w przypadku jednego z moich projektów. Dobra, podstawowa technika. Właśnie testowałem go w Visual Studio 2008, a to działa:

var mockMessage1 = new Mock<IMessage>(); 
var mockMessage2 = new Mock<IMessage>(); 
var mockMessage3 = new Mock<IMessage>(); 

var messageQueue = new Queue<IMessage>(new [] { mockMessage1.Object, mockMessage2.Object, mockMessage3.Object }); 

var mockMsmqWrapper = new Mock<IMsmqWrapper>(); 

mockMsmqWrapper.Setup(x => x.GetMessage()).Returns(() => messageQueue.Dequeue()).Callback(() => 
{ 
    if (messageQueue.Count == 0) 
     mockMsmqWrapper.Setup(x => x.GetMessage()).Throws<MyCustomException>(); 
}); 

Kilka uwag:

  1. Nie musiał wrócić szydzili wiadomości, ale jest to przydatne, jeśli chcesz zweryfikować oczekiwania na każdej wiadomości, aby sprawdzić, czy określone metody zostały wywołane lub czy zostały ustawione właściwości.
  2. Idea kolejki nie jest moją własnością, tylko wskazówka, którą otrzymałem od posta na blogu.
  3. Powodem, dla którego zgłaszam wyjątek MyCustomException jest to, że klasa Queue automatycznie zgłasza wyjątek InvalidOperationException. Chciałem się upewnić, że wyśmiewany obiekt MsmqWrapper zgłasza wyjątek z powodu Moq, a nie z powodu kończącej się kolejki elementów.

Oto pełny kod, który działa. Należy pamiętać, że ten kod jest brzydki, w niektórych miejscach, ale chciałem tylko pokazać, jak może to być testowane:

public interface IMsmqWrapper 
{ 
    IMessage GetMessage(); 
} 

public class MsmqWrapper : IMsmqWrapper 
{ 
    public IMessage GetMessage() 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class Processor 
{ 
    private IMsmqWrapper _wrapper; 
    public int MessagesProcessed { get; set; } 
    public bool ExceptionThrown { get; set; } 

    public Processor(IMsmqWrapper msmqWrapper) 
    { 
     _wrapper = msmqWrapper;   
    } 

    public virtual void ProcessMessages() 
    { 
     _wrapper.GetMessage(); 
     MessagesProcessed++; 
     _wrapper.GetMessage(); 
     MessagesProcessed++; 
     _wrapper.GetMessage(); 
     MessagesProcessed++; 

     try 
     { 
      _wrapper.GetMessage(); 
     } 
     catch (MyCustomException) 
     { 
      ExceptionThrown = true; 
     } 
    } 
} 

[Test] 
public void TestMessageQueueGetsExhausted() 
{ 
    var mockMessage1 = new Mock<IMessage>(); 
    var mockMessage2 = new Mock<IMessage>(); 
    var mockMessage3 = new Mock<IMessage>(); 

    var messageQueue = new Queue<IMessage>(new [] { mockMessage1.Object, mockMessage2.Object, mockMessage3.Object }); 

    var mockMsmqWrapper = new Mock<IMsmqWrapper>(); 
    mockMsmqWrapper.Setup(x => x.GetMessage()).Returns(() => messageQueue.Dequeue()).Callback(() => 
    { 
     if (messageQueue.Count == 0) 
      mockMsmqWrapper.Setup(x => x.GetMessage()).Throws<InvalidProgramException>(); 
    }); 

    var processor = new Processor(mockMsmqWrapper.Object); 

    processor.ProcessMessages(); 

    Assert.That(processor.MessagesProcessed, Is.EqualTo(3)); 
    Assert.That(processor.ExceptionThrown, Is.EqualTo(true)); 
} 
Powiązane problemy