Bei recherchen im Internet über das Thema Mock Objects und Stub Objects bin ich auf einen interessanten Artikel von Jay Fields gestossen: Use stubs and mocks to convey intent. Darin ist meiner Meinung nach gut beschrieben, in welchem Fall man besser ein Mock und wann ein Stub Object verwendet.
Archiv für die Kategorie ‘Tests’
Wann Stub und wann Mock Objects verwenden
Montag, 19. Juni 2006NCover: Attribute-Based Type Exclusion, but the wrong way round…
Dienstag, 21. Februar 2006With Version 1.5.2, NCover introduced a Attribute-Based Type Exclusion. It works, but not as I expected.
I normally use NCover together with my test code. When I have a class to test that throws an exception the test function is not covered completely.

The function BarTest() is only covered to 67% as the end of the function is not executed because the Exception was thrown. I was waiting for the possibility to define that a function does not need to be covered with adding an attribute to the Function. But when I add an Attribute to the function and define this Attribute to be excluded (with //ea AttributeName), the Function is not covered.

So instead of having a higher code coverage I have a lower code coverage. Not the result I was expecting from this feature.
But maybe this will change in the future. I keep watching…
Jay Fields Thoughts: Creating an interface for testing
Montag, 20. Februar 2006The article from Jay Fields about creating an interface for testing should be read by each developer that uses unit tests (and that should be every developer!) I had several discussions about my ‘Interface-flooded’ code, and this article is a good explanation for my behaviour.
Mocks Aren’t Stubs or State-Based vs Ineraction-Based Tests
Sonntag, 19. Februar 2006While looking for a definition for Stubs and Mocks I stumbled over an article from Martin Fowler that makes a comparing between State-Based and Interaction-Based testing. Never thougt about my tests in this way, worth reading it.
Code Coverage mit NCover und NCoverExplorer
Sonntag, 05. Februar 2006Grant Drake hat sein Tool NCoverExplorer vorgestellt. NCoverExplorer ist ein Tool, um die Reports von NCover komfortabel zu begutachten.Wer NCoverBrowser von Jeff Key kennt wird sich damit sofort zurechtfinden, da NCoverExplorer nach dem Vorbild von NCoverBrowser erstellt wurde. Grant betrieb diesen Aufwand, da der Sourcecode von NCoverBrowser nicht frei verfügbar ist (wegen komerzieller Komponenten, die eingesetzt wurden).
NCoverExplorer wird mit TestDriven.NET ausgeliefert, benötigt aber noch NCover. Dann kann aber direkt aus der Entwicklungsumgebung (auch aus Visual C# Express Edition) der Coverage Report geöffnet werden:
Fallstricke bei NMock mit Klassen
Mittwoch, 25. Januar 2006Mit NMock können Attrappen (Mock Objetcs) für Klassen und Interfaces erzeugt werden. Ein deutscher Artikel über NMock ist beim dot.net magazin online abrufbar. Falls Mock Objects für Klassen erstellt werden, müssen einige Dinge beachtet werden.
1. Funktionen und Properties müssen virtual sein
Funktionen und Properties, welche durch das Mock Object ersetzt werden sollen, müssen als
deklariert werden, da NMock diese sonst nicht überschreiben kann.
NMock wirft normalerweise eine Exception, falls man eine Funktion mit
,
,
oder
konfiguriert und diese nicht virtual ist.
Wenn aber ein Property nicht als
deklariert wird und mit
das Verhalten überschrieben werden soll, wird keine Exception generiert. Es wird aber beim Aufrufen des Properties der Code der zu ersetzenden Klasse aufgerufen:
{
public string Bar
{
get { return "bar"; }
}
}
[TestFixture]
public class TestingClass
{
[Test]
public void MockTest()
{
DynamicMock mock = new DynamicMock(typeof(ClassToMock));
mock.SetupResult("Bar", "foo");
ClassToMock c = (ClassToMock)mock.MockInstance;
Assert.AreEqual("foo", c.Bar);
}
}
Dieser Test schlägt Fehl, da immer noch der Code der Klasse
aufgerufen wird und somit der Text “bar” und nicht der Text “foo”, wie eigentlich erwartet, zurückgegeben wird. Sobald das Property als
deklariert wird, kann der Test erfolgreich ausgeführt werden.
Nicht virtuelle Funktionen können auch nicht durch den “Strict” Mechanismus überwacht werden. Folgender Test sollte eigentlich fehlschlagen, da es nicht erwartet wird, dass die Funktion
aufgerufen wird (kein
). Der Test wird aber erfolgreich ausgeführt.
{
public void Foo() {}
}
[TestFixture]
public class TestingClass
{
[Test]
public void MockTest()
{
DynamicMock mock = new DynamicMock(typeof(ClassToMock));
mock.Strict = true;
ClassToMock c = (ClassToMock)mock.MockInstance;
c.Foo();
mock.Verify();
}
}
Sobald man Foo als
deklariert schlägt der Test wie erwartet fehl.
2. Wenn Strict benutzt wird muss Finalize als expected angegeben werden
Durch setzten des Attributes
auf
wird NMock angewiesen, dass alle Funktionsaufrufe vorher angemeldet werden müssen. Das gilt auch für den Destruktor, der am Ende der Lebenszeit des Objekts aufgerufen wird.
Da der Destruktor (Methode
) durch den Garbage Collector aufgerufen wird hat man keine Kontrolle darüber, wann der Destruktor aufgerufen wird. Bei den Tests wird er normalerweise nach den eigentlichen Tests aufgerufen. Deshalb wird eine fehlende Finalize-Anmeldung auch nicht als fehlschlagender Test gewertet, es wird aber eine Fehlermeldung auf die Error-Konsole ausgegeben, was nicht sehr Vertrauenserweckend wirkt.
Wenn man die Tests mit NUnit-GUI oder mit dem Visual-Studio-PlugIn TestDriven.NET ausführt ist diese Fehlermeldung nicht sichtbar.
Folgender Code erzeugt die Fehlermeldung:
{
}
[TestFixture]
public class TestingClass
{
[Test]
public void MockTest()
{
DynamicMock mock = new DynamicMock(typeof(ClassToMock));
mock.Strict = true;
ClassToMock c = (ClassToMock)mock.MockInstance;
mock.Verify();
}
}
Wenn der Test mit nunit-console aufgerufen wird, wird am Schluss folgende Fehlermeldung ausgegeben:
expected:0
but was:<1>
at NMock.Mock.Invoke(String methodName, Object[] args)
at ProxyClassToMock.Finalize()
Wenn man nun aber am Anfang des Codes folgende Zeile einfügt:
reklamiert die Funktion
zu Recht, da der Destruktor zu diesem Zeitpunkt noch nicht aufgerufen wurde.
Man kann die oben angegebene Zeile aber nach den letzten
-Aufruf setzten. Dadurch wird das Mock Object auf den Destruktor vorbereitet, welcher dann am Ende des Testes aufgerufen wird. Dieser Code kann z.B. in den
-Bereich eines Testes geschrieben werden.
Owen Rogers, auch bekannt unter dem Namen exortech, hat diesen Bug auch entdeckt und in seinem Blog beschrieben. Scheinbar hat aber diese Änderung den Weg in den Code von NMock nicht gefunden…