2012-06-12 7 views
24

Ich habe eine Klasse, die durch einen Delegaten erhalten Argument aufgerufen. Diese Klasse ruft diesen Delegaten auf, und ich möchte ihn mit Moq testen. Wie überprüfe ich, dass diese Methode aufgerufen wurde?Überprüfung eines Delegaten wurde mit Moq

Beispielklasse:

public delegate void Foo(int number); 

public class A 
{ 
    int a=5; 

    A (Foo myFoo) 
    { 
     Foo(a); 
    } 
} 

und ich möchte überprüfen, ob Foo aufgerufen wurde. Danke.

+3

Ich denke das Sie müssen die Antwort ändern, da die Antwort von @Lukazoid zutreffender ist als Ihre Wahl. –

+0

Sollte im Konstruktor die Zeile 'myFoo (a)' lauten? Sie rufen diese Instanz von 'Foo' auf, nicht die' Foo' Klasse selbst, oder? –

Antwort

28

Wie wäre es mit einer anonymen Funktion? Es kann sich hier wie ein Inline-Mock verhalten, Sie brauchen kein Spott-Framework.

bool isDelegateCalled = false; 
var a = new A(a => { isDelegateCalled = true}); 

//do something 
Assert.True(isDelegateCalled); 
3

Moq unterstützt keine Spottdelegationen. Aber man kann etwas Schnittstelle, mit der Methode erstellen, die Ihre Unterschrift Delegaten matches:

public interface IBar 
{ 
    void M(int number); 
} 

Dann Mock erstellen, die diese Schnittstelle implementiert, und verwenden Sie dieses Mock-Objekt delegieren zu erstellen:

Mock<IBar> bar = new Mock<IBar>(); 
Foo foo = new Foo(bar.Object.M); 
A a = new A(foo); 
bar.Verify(x => x.M(5)); 

Nach dem Sport Ihr sut, Sie können die Erwartungen an Ihr verspottetes Objekt überprüfen.

UPDATE: Eigentlich können Sie einfach bar.Object.M an Ihre sut übergeben, ohne Foo Delegate Instanz erstellen. Aber wie auch immer, das Spotten von Delegierten erfordert die Erstellung von Schnittstellen.

+0

Nur ein FYI, Moq unterstützt jetzt das Spott der Delegierten siehe meine Antwort und [hier] (https://github.com/Moq/moq4/commit/e614ae5b4a14896503b59e2a70ac799bb66e741b) – Lukazoid

3

Sie können so etwas tun:

public interface IWithFOOMethod 
{ 
    void FooAlikeMethod(int number); 
} 

Mock<IWithFOOMethod> myMock = new Mock<IWithFOOMethod>(); 

A a = new A(myMock.Object.FooAlikeMethod); 

myMock.Verify(call => call.Foo(It.IsAny<int>()), Times.Once()) 
1

Da Moq unterstützt keine Delegierten spöttisch, ich werde dies in der Regel, wie mit etwas umgehen:

var list = new List<int>(); 
var del = i => list.Add (i); 
var a = new A(del); 
list.ShouldContainOnly (new[] { 5 }); 

, wo der vorgesehenen Delegierten führt einige einfaches, überprüfbares Handeln.

+1

Nur ein FYI, unterstützt Moq jetzt das Spott der Delegierten siehe mein antwort und [hier] (https://github.com/Moq/moq4/commit/e614ae5b4a14896503b59e2a70ac799bb66e741b) – Lukazoid

32

Ab this commit Moq unterstützt nun die Verspottung Delegierten, für Ihre Situation würden Sie es wie so tun:

var fooMock = new Mock<Foo>(); 
var a = new A(fooMock.Object); 

Dann können Sie die Delegierten überprüfen aufgerufen wurde:

fooMock.Verify(f => f(5), Times.Once); 

Oder:

fooMock.Verify(f => f(It.IsAny<int>()), Times.Once); 
Verwandte Themen