2013-04-24 9 views
7

sto cercando di estendere il metodo xUnit assert con l'aggiunta di alcune funzionalità selenioEstendere classe xUnit Assert con la nuova afferma

namespace MyProject.Web.Specs.PageLibrary.Extensions 
{ 
    public static class AssertExtensions 
    { 
     public static void ElementPresent(this Assert assert, ...) 
     { 
      if (...) 
      { 
       throw new AssertException(...); 
      } 
     } 
    } 
} 

Ma io ottenere questo errore di compilazione quando provo ad usarlo.

using MyProject.Web.Specs.PageLibrary.Extensions;  
using Xunit; 
... 

public void DoSomething() 
{ 
    Assert.ElementPresent(...); 
} 

E l'errore

Error 5 'Xunit.Assert' does not contain a definition for 'ElementPresent' 

Qualcuno sa se questo è possibile o dove sto andando male?

risposta

3

È necessario l'oggetto intance che verrà passato come argomento al metodo di estensione. Nel tuo caso questo sarebbe sintassi corretta

var assert = new Assert(); 
assert.ElementPresent(...); 

ma suppongo che non è necessario o addirittura non in grado di creare un'istanza della classe Assert.

Quello che stai cercando di fare è chiamare il metodo di estensione come invocazione statica su una classe estesa e che non funzionerà. Ma perché non sufficiente chiamare

AssertExtensions.ElementPresent(...); 
+0

Grazie, che spiega il motivo per cui non ho potuto ottenere l'asserzione di estendere come avrei voluto. La tua soluzione è praticamente ciò che ho finito, ma ho chiamato il mio 'SeleniumAssert.ElementPresent (...);' – Neil

+1

Per xUnit 2, controlla gli esempi come https://github.com/xunit/samples.xunit /blob/master/AssertExtensions/StringAssertionExtensions.cs – Jedidja

3

Ci dispiace, ma stai sempre confuso (EDIT: e così ero io). xUnit.net's è static e quindi non è possibile aggiungere estensioni (anche se altre librerie di asserzioni non fanno causa a questo approccio, motivo per cui ci si potrebbe aspettare di utilizzare i metodi di estensione per estendere Assert). Quindi, nell'universo xUnit.net, se si desidera aggiungere un'asserzione personalizzata, aggiungere una nuova classe statica con un nome diverso.

È possibile rendere il vostro lavoro approccio cambiando la classe da:

public static class AssertExtensions 
{ 
    public static void ElementPresent(this Assert assert, ...) 

a:

public class AssertExtensions : XUnit.Assert 
{ 
    public static void ElementPresent(...) 

e quindi utilizzando @ trucco di BradWilson di aggiungere:

using Assert = MyProject.Web.Specs.PageLibrary.Extensions.AssertExtensions; 

a la parte superiore di qualsiasi file che richiede le tue estensioni.

Questa tecnica è utile per l'aggiunta di sovraccarichi venire a pensarci bene ....

(La debolezza evidente è che non si può avere più di un accessibile direttamente tramite Assert. però)

+0

La classe 'Assert' non è statica, ma i metodi all'interno sono statici, questo è quello che mi ha stancato. Guarda la soluzione per @jure – Neil

+0

@Neil. Grazie per il downvote. Sto conversando con @xunit che sta vedendo se 'Assert' può diventare una classe statica per evitare che qualcun altro si imbatta in questo (è una sorpresa per me che non è come xUnit.net dipende da .NET 2.0 che consente classi statiche e non posso pensa come il cambiamento potrebbe essere interrotto.) –

+0

@Neil Ah, sembra che potrebbe essere stato lasciato aperto per abilitare il trucco di estensione descritto [qui] (https://xunit.codeplex.com/discussions/15792). Infine, il motivo per cui ero così sicuro che fosse "statico" - Brad Wilson stesso mi disse che era: - https://xunit.codeplex.com/discussions/238521 –

10

Edit 2 xUnit 2 alla fine ha finito per spostare le asserzioni in un assembly separato del tutto. Vi sono sia pacchetti compilati che di sola origine di questo su NuGet e la classe Assert è parziale, quindi utilizzando la sola versione di origine del pacchetto, Assert diventa molto facilmente estendibile (in C#, cioè).

Modifica Per ulteriori completezza: xUnità 2 rimuove questo punto di estensione e consiglia di utilizzare i metodi di estensione sulla falsariga delle librerie di asserzione "fluente".


Per completezza, ecco una descrizione del modo "ufficiale" di estendere Assert (che sorprendentemente non è stato menzionato a tutti, nonostante il fatto che Brad Wilson anche aderito la discussione).

Dalla versione 1.5 (secondo il blog di Brad), xUnit.Extensions ha il supporto esplicito per questo tramite le classi Assertions e TestClass. Funziona così:

TestClass ha una proprietà chiamata Assert che è di tipo Assertions che trasmette tutti i metodi su Xunit.Assert. Perché TestClass.Assert è un esempio, è possibile aggiungere metodi ad esso attraverso metodi di estensione su Assertions:

public static class AssertionsExtensions 
{ 
    public static void DeepEquals(this Assertions assertions, XNode expected, XNode actual) 
    { 
     assertions.True(XNode.DeepEquals(expected, actual)); // You can also use Assert.True here, there's effectively no difference. 
    } 
} 

Ora è necessario avere la classe di test derivare da Xunit.Extensions.TestClass (confusamente, c'è anche Xunit.TestClass, che non è quello che si vuole) e la proprietà Assert "ombreggia" il tipo Xunit.Assert se non si qualifica esplicitamente il nome.

Nella tua classe di test che deriva da TestClass, è ora possibile utilizzare

Assert.DeepEquals(expectedXml, actualXml); 

L'unica vera differenza da un built-in xUnit affermazione (a parte il fatto che la colorazione della sintassi per Assert è quella di un identificatore , non un tipo) è che quando fallisce, si ottiene semplicemente un, non uno specifico DeepEqualsException che potrebbe ipoteticamente dirti dove il confronto non è riuscito a. Ma ovviamente puoi costruirlo anche nello stesso modo.

+0

Dai un'occhiata al post di Ruben Bartelink .. sotto. Insieme con le conoscenze qui sopra si ottiene la creazione del proprio derivatoin da global :: XUnit.Assert – Robetto

+1

E per xUnit 2, la cosa più semplice è controllare gli esempi come https://github.com/xunit/samples.xunit /blob/master/AssertExtensions/StringAssertionExtensions.cs – Jedidja

3

Riepilogo della soluzione per xUnità 2. (Ha funzionato per me per la versione 2.1.0 di NuGet.)

L'assert è una classe parziale che è possibile estendere aggiungendo un'altra parte. Per essere in grado di farlo è necessario compilare l'Assert Assembly dai sorgenti. È possibile utilizzare xunit.assert.source NuGet per ottenere i sorgenti.

Piazza

  1. Rimuovere riferimento al xunit.assert pacchetto NuGet dal progetto.
  2. Installare invece il pacchetto xunit.assert.source.
  3. Nello spazio nomi Xunit, definire public partial class Assert e aggiungere qui i propri asserti personalizzati.

Esempio di affermare personalizzato:

namespace Xunit 
{ 
    public partial class Assert 
    { 
     public static void ArraySegmentEqual<T>(
      T[] expectedSequence, T[] buffer, int offset = 0) 
     { 
      for (int i = 0; i < expectedSequence.Length; i++) 
      { 
       int b = i + offset; 

       True(buffer[b].Equals(expectedSequence[i]), 
        $"Byte #{b} differs: {buffer[b]} != {expectedSequence[i]}"); 
      } 
     } 
    } 
} 

Nota: Altre risposte e le modifiche sottolineano anche la soluzione, ma mi ci sono voluti un po 'di tome per capirlo da lì. Inoltre, non ritengo che questa sia l'unica o l'opzione migliore.

0

Per xUnit 2+:

1) Aggiungere xunit.assert.source pacchetto Nuget al progetto con le estensioni.

2) Creazione di definizione della classe parziale:

namespace xUnit 
{ 
    public partial class Assert 
    { 
    public static void ElementPresent(...) 
    { 
    } 
    } 
}