2012-08-24 4 views
5

Ecco parte di implementazione del codice in classe padre:Come aumentare un evento in un test che utilizza Moq?

handler.FooUpdateDelegate += FooUpdate(OnFooUpdate); 
protected abstract void OnFooUpdate(ref IBoo boo, string s); 

ho nel metodo di prova gestore deriso:

Mock<IHandler> mHandler = mockFactory.Create<IHandler>(); 

Questa ...

mHandler.Raise(x => x.FooUpdateDelegate += null, boo, s); 

... non è lavoro. Dice:

System.ArgumentException: Impossibile trovare l'evento per il metodo attach o detach. Void set_FooUpdateDelegate (FooUpdate).

Voglio sollevare OnFooUpdate in modo da attivare il codice da testare in classe figlio.

Domanda: Come posso aumentare il delegato (gestore di eventi non comune) con Moq?

Se ho perso completamente il punto, ti prego di informarmi.

risposta

8

Sembra che tu stia cercando di aumentare un delegato piuttosto che un evento. È così?

Il tuo codice è sulla falsariga di questo?

public delegate void FooUpdateDelegate(ref int first, string second); 

public class MyClass { 
    public FooUpdateDelegate FooUpdateDelegate { get; set; } 
} 

public class MyWrapperClass { 

    public MyWrapperClass(MyClass myclass) { 
     myclass.FooUpdateDelegate += HandleFooUpdate; 
    } 

    public string Output { get; private set; } 

    private void HandleFooUpdate(ref int i, string s) { 
      Output = s; 
    } 

} 

Se è così, allora è possibile richiamare direttamente la myClass FooUpdateDelegate in questo modo

[TestMethod] 
public void MockingNonStandardDelegate() { 

    var mockMyClass = new Mock<MyClass>(); 
    var wrapper = new MyWrapperClass(mockMyClass.Object); 

    int z = 19; 
    mockMyClass.Object.FooUpdateDelegate(ref z, "ABC"); 

    Assert.AreEqual("ABC", wrapper.Output); 

} 

EDIT: Aggiunta versione utilizzando l'interfaccia

public interface IMyClass 
{ 
    FooUpdateDelegate FooUpdateDelegate { get; set; } 
}  

public class MyClass : IMyClass { 
    public FooUpdateDelegate FooUpdateDelegate { get; set; } 
} 

public class MyWrapperClass { 

    public MyWrapperClass(IMyClass myclass) { 
     myclass.FooUpdateDelegate += HandleFooUpdate; 
    } 

    public string Output { get; private set; } 

    private void HandleFooUpdate(ref int i, string s) { 
      Output = s; 
    } 

} 


[TestMethod] 
public void MockingNonStandardDelegate() 
{ 

    var mockMyClass = new Mock<IMyClass>(); 
    // Test fails with a Null Reference exception if we do not set up 
    // the delegate property. 
    // Can also use 
    // mockMyClass.SetupProperty(m => m.FooUpdateDelegate); 

    mockMyClass.SetupAllProperties(); 

    var wrapper = new MyWrapperClass(mockMyClass.Object); 

    int z = 19; 
    mockMyClass.Object.FooUpdateDelegate(ref z, "ABC"); 

    Assert.AreEqual("ABC", wrapper.Output); 

} 
+0

Grande risposta. Una cosa che vorrei ricordare è che potrebbe essere necessario mantenere la proprietà FooUpdateDelegate, chiamando mockMyClass.SetupAllProperties() – Eternal21

+1

@ Eternal21 Il Mock sta utilizzando l'implementazione concreta della proprietà da MyClass, quindi funziona così com'è. Se stessimo prendendo in giro un'interfaccia (ad esempio, IMyClass), non ci sarebbe stata alcuna implementazione concreta e sarebbe stata necessaria la creazione della proprietà sulla simulazione. – AlanT

+0

Questo era esattamente il mio caso. – Eternal21