Schlagwort-Archive: ReSharper

MSpec mit ReSharper 7

Soeben habe ich testweise von ReSharper 6 auf Version 7 aktualisiert.

image

Wie auch bei den letzten Upgrades fehlen danach zunächst die Plugins:

image

Zunächst habe ich mit der aktuellen Version 0.5.7 die Installation versucht. Hier fehlt zwar noch das entsprechende Installationsskript für VS2010 + R# 7, aber das ist schnell gebastelt. Leider half dies nichts.

Um eine lange Geschichte abzukürzen: Auch Version 0.5.8 Beta 9 löst das Problem nicht. Ich habe die Info bereits an Alexander Gross von GROSSWEBER weitergeleitet.

Aktualisierung von 23.08 Uhr: AGross teilte mir soeben mit, dass er morgen die finale 0.5.8 bereitstellen will, die das Problem lösen sollte!

Aktualisierung von 23.17 Uhr: Wer nicht warten kann, installiert sich die Version 0.5.8 Beta 11. Danach läuft alles geschmeidig:

Install-Package Machine.Specifications -Version 0.5.8-beta11 -Pre

imageimage

Werbung

UnitTests & Threading – Ist grün wirklich grün?

Ich bin kürzlich auf ein Problem gestoßen: In ReSharper wurden UnitTests grün angezeigt, obwohl diese fehlschlugen. Im konkreten Fall handelt es sich um einen UnitTest im Rahmen von Logik, die parallel abläuft. Tritt in den Threads eine Exception auf, so wird dies nicht als Fehler behandelt. Der UnitTest ist weiterhin grün, wenn der Assert trotzdem korrekt ist.

Beispiel: Stellen wir uns zwei Worker Threads vor, die bei einem Controller nach neuen Druckaufträgen fragen. Der Controller ist als Singleton implementiert (oder idealerweise wird dies schon out of the box vom IoC Container gemacht). Tritt nun eine Exception in den Threads auf, der Assert ist aber trotzdem korrekt, so wird der UnitTest grün angezeigt. Hier der Code dazu:

Implementierung Controller:

   1: class PrintJobMediator : IMediatePrintjobs

   2: {

   3:     //lock object for the method

   4:     private object _lockObject = new object();

   5:  

   6:     //instance of the singleton

   7:     private static volatile PrintJobMediator instance;

   8:  

   9:     //lock object for singleton

  10:     private static object syncRoot = new Object();

  11:  

  12:     //private ctor

  13:     private PrintJobMediator() { }

  14:  

  15:     //returns the singleton instance

  16:     public static PrintJobMediator Instance

  17:     {

  18:         get

  19:         {

  20:             if (instance == null)

  21:             {

  22:                 lock (syncRoot)

  23:                 {

  24:                     if (instance == null)

  25:                         instance = new PrintJobMediator();

  26:                 }

  27:             }

  28:  

  29:             return instance;

  30:         }

  31:     }

  32:  

  33:     int _result;

  34:     public int Next()

  35:     {

  36:         lock (_lockObject)

  37:         {

  38:             System.Threading.Thread.Sleep(1000);

  39:             _result += 1;

  40:  

  41:             if (_result == 1)

  42:                 throw new ApplicationException();

  43:         }

  44:  

  45:         return _result;

  46:     }

  47: }

Unit Test:

   1: [Subject(typeof(PrintJobMediator))]

   2: public class When_2_worker_ask_for_new_jobs

   3: {

   4:     static PrintJobMediator _jobMediator;

   5:     static Thread _thread1;

   6:     static Thread _thread2;

   7:     static TimeSpan _timeTaken;

   8:  

   9:     Establish context = () =>

  10:     {

  11:         _jobMediator = PrintJobMediator.Instance;

  12:         _thread1 = new Thread(() => _jobMediator.Next());

  13:         _thread2 = new Thread(() => _jobMediator.Next());

  14:     };

  15:  

  16:     Because of = () =>

  17:     {

  18:         _timeTaken = Measure.Time(() =>

  19:         {

  20:             _thread1.Start();

  21:             _thread2.Start();

  22:             _thread1.Join();

  23:             _thread2.Join();

  24:         });

  25:     };

  26:  

  27:     It should_run_jobs_sequentially = () => _timeTaken

  28:         .ShouldBeGreaterThanOrEqualTo(TimeSpan.FromSeconds(2));

  29: }

  30:  

  31: public static class Measure

  32: {

  33:     public static TimeSpan Time(Action timedAction)

  34:     {

  35:         var watch = new System.Diagnostics.Stopwatch();

  36:         watch.Start();

  37:  

  38:         timedAction();

  39:  

  40:         watch.Stop();

  41:         return watch.Elapsed;

  42:     }

  43: }

 

In ReSharper wird der Test als erfolgreich angezeigt:

image

Wenn man sich die Details anschaut, sieht man folgendes:

image

In der Implementierung schmeiße ich im ersten Thread eine Exception (Zeile 42). Da trotzdem die Gesamtdauer der Ausführung 2 Sekunden ist, ist der Assert korrekt. Der UnitTest bricht nicht ab, weil seit .NET 2.0 eine neue Policy greift (Name fällt mir gerade nicht mehr ein), die den Abbruch des Main Thread durch Exceptions in separaten Threads verhindert.

ReSharper–Patterns

Wer ReSharper einsetzt, kann seine Code Qualität dadurch erhöhen, dass er die Patterns Funktionalität in der Code Inspection nutzt. Damit erkennt ReSharper typische Anti Patterns. Ein Beispiel für ein Anti Pattern habe ich hier beschrieben.

JetBrains bietet euch bereits eine definierte Liste, welche ihr hier (Download von ‘Sample pattern catalog for Structural Search and Replace’) findet. Dabei handelt es sich um eine XML File, welche ihr in den Optionen unter Code Inspection – Custom Patterns importieren könnt.

image

ReSharper & IoC Container

Wer in seiner Architektur auf IoC Container einsetzt, der bekommt bei ReSharper immer die Meldung “Possible NullReferenceException”, wenn er z.B. im Konstruktor den NULL-check unterlässt. Allerdings ist diese Prüfung meiner Meinung nach unnötig, da der Container ja entweder eine Instanz erzeugen kann oder ggf. eine Exception schmeißt. Deshalb würde ich diese Prüfung in ReSharper abschalten:

Geht dazu in eure ReSharper Optionen (Achtung: Ab Version 6.1 gibt es ja unterschiedliche Layer an Optionen. Achtet darauf, dass ihr im richtigen Layer seid!). Danach findet ihr unter Code Inspection – Inspection Severity im Tab All, wenn ihr beim Filter “null” eingebt unter der Kategorie “Potential Code Quality Issues” die Option “Possible System.NullReferenceException”, welche ihr auf “Do not show” stellen müsst.

image

ReSharper Settings für Unit Tests

Wer Probleme bei seinen Unit Tests hat, weil für den Unit Tests die Assemblies in ein temporäres Verzeichnis kopiert und dort ausgeführt werden, der kann dies in den ReSharper Settings über die Settings “Shadow-copy assemblies being tested” deaktivieren.

Bei mir traten Probleme in einem Unit Test für meinen IoC-Container auf. Hintergrund ist der, dass im Test alle DLLs nach IWindsorInstaller Implementierungen durchsucht und registriert werden. Da nicht alle DLLs vorhanden waren, kam es zu Fehlern.

image

%d Bloggern gefällt das: