2014-01-30 8 views
21

Ich möchte Methode A meiner Klasse testen, aber ohne die tatsächliche Methode B aufzurufen, die normalerweise von A aufgerufen wird. Das liegt daran, dass B viele externe Interaktionen hat, die ich jetzt nicht testen möchte.Mock eine Methode des Probanden im Test in Moq?

Ich könnte Mocks für alle von B genannten Dienste erstellen, aber das ist ziemlich viel Arbeit. Ich würde B lieber verspotten und dafür sorgen, dass Beispieldaten zurückgegeben werden.

Ist das mit Moq Framework möglich?

Antwort

28

Es ist, mit einem Haken! Sie müssen sicherstellen, dass die Methode B virtuell ist und überschrieben werden kann.

Setzen Sie den Mock anschließend so, dass er die Basismethoden aufruft, wenn kein Setup bereitgestellt wird. Dann richten Sie B ein, aber richten Sie A nicht ein. Da A nicht eingerichtet wurde, wird die eigentliche Implementierung aufgerufen.

var myClassMock = new Mock<MyClass>(); 
myClassMock.Setup(x => x.B()); //mock B 

myClassMock.CallBase = true; 

MyClass obj = myClassMock.Object; 
obj.A(); // will call the actual implementation 
obj.B(); // will call the mock implementation 

Behinds die Kulissen, Moq wird dynamisch eine Klasse erstellen, die MyClass erweitert und überschreibt B.

+2

Genau, und es wird am einfachsten sein, wenn die 'virtuelle' Methode' B' entweder 'geschützt intern' oder 'öffentlich' ist. –

+0

Frage: Was ist die Zeile CallBase = true; machen? – Hace

+1

@Hace Wenn ich mich richtig erinnere, teilt es dem Mock-Objekt mit, die Methoden, die in 'MyClass' definiert sind, aufzurufen, es sei denn, ein explizites Setup wird bereitgestellt. Wenn Sie "CallBase = true" nicht aufgerufen haben, würde Moq eine falsche Implementierung jeder virtuellen Methode aufrufen, unabhängig davon, ob eine explizite Konfiguration bereitgestellt wurde. – dcastro