2015-08-07 20 views
9

ho questo codice:Come posso prendere in giro questo metodo statico

public static bool IsValidVoucher(string id) 
{ 
    //read tsv files 
    var temp1 = AppData.GetAppData("stringval");    
    // code that need to be tested   
    return true;   
} 

e mi piace creare unit test, ma come posso prendere in giro AppData.GetAppData("stringval") a quello che voglio è il valore, così posso testare il resto di codice.

classe L'AppData è:

public class AppData 
{ 
    public static object GetAppData(string name) 
    { 
     //... 
    } 
} 
+0

Invece di hardcoding 'AppData.GetAppData' si potrebbe iniettare una classe che fa la lettura del AppData e poi nella vostra unit test, prendi in giro quella lezione e imposta il valore di ritorno che ti serve. – LInsoDeTeh

+0

Con Moq non possibile senza ulteriori modifiche del codice sorgente. Ma con [Typemock's Isolator] (http://www.typemock.com/isolator-features/test-the-un-estestable/fake-static-methods.html) è possibile. Tuttavia Isolator non è gratuito. – dee

+0

E [qui] (http://adventuresdotnet.blogspot.de/2011/03/mocking-static-methods-for-unit-testing.html) qualche altra informazione sui metodi statici di simulazione. E [qui] (http://stackoverflow.com/questions/5864076/mocking-static-methods) risposta da SO. HTH – dee

risposta

6

I metodi statici non possono essere deriso in modo semplice. Che, fondamentalmente, hanno due scelte:

  1. Se si possiede la classe AppData, modificare l'implementazione per implementare un'interfaccia (ad esempio IAppData) e rimuovere il modificatore static sul metodo GetAppData in modo da poter prendere in giro esso.

    public interface IAppData 
    { 
        object GetAppData(string id); 
    } 
    
    public class AppData : IAppData 
    { 
        public object GetAppData(string id) {} 
    } 
    
    public class Foo 
    { 
        private readonly IAppData _appData; 
    
        public Foo(IAppData appData) 
        { 
         _appData = appData; 
        } 
    
        public bool IsValidVoucher(string id) 
        { 
         // Call through object instance instead for class reference 
         var temp1 = _appData.GetAppData("stringval"); 
        } 
    } 
    
  2. Se non si possiede la classe AppData, utilizzare una classe wrapper (ad es AppDataWrapper) che implementa un'interfaccia e chiamare quel metodo da IsValidVoucher invece:

    public interface IAppData 
    { 
        object GetAppData(string id); 
    } 
    
    public class AppDataWrapper : IAppData 
    { 
        public object GetAppData(string id) 
        { 
         return AppData.GetAppData(id); 
        } 
    } 
    
    public class Foo 
    { 
        private readonly IAppData _appData; 
    
        public Foo(IAppData appData) 
        { 
         _appData = appData; 
        } 
    
        public bool IsValidVoucher(string id) 
        { 
         var temp1 = _appData.GetAppData("stringval"); 
        } 
    } 
    

È quindi possibile unit test Foo usando Moq (usando xunit come esempio qui):

public class FooTests 
{ 
    private readonly IAppData _mockAppData; 

    public FooTests() 
    { 
     var mockAppData = new Mock<IAppData>(); 
     mockAppData.Setup(m => m.GetAppData(It.IsAny<string>)).Returns("my test value"); 
     _mockAppData = mockAppData.Object; 
    } 

    [Fact] 
    public void IsValidVoucher_ValidAppData_Returns() 
    { 
     var foo = new Foo(_mockAppData); 
     // Unit test foo.IsValidVoucher 
    } 
} 
+0

Hai detto che i metodi statici non possono essere derisi ... Vedi la mia risposta; P Forse è un'idea pazzesca, ma funziona! –

+0

@ MatíasFidemraizer, dovrei dire che il metodo statico non può essere deriso ** in modo semplice **;) Modificato per chiarezza – rexcfnghk

+0

Posso solo dire * lol * –

1

Bene, penso che i commenti di tutti fino ad ora siano tecnicamente corretti - usando qualcosa come RhinoMocks o Moq, non si può davvero prendere in giro metodi statici in modo facile e diretto.

Ma usando Moles, è sicuramente possibile. Quindi, se hai codice significativo (attualmente) non testabile che risiede in metodi statici, penso che dovresti esaminare Moles.

(Questo link è un po 'datato, ma trovo ancora utile) http://research.microsoft.com/en-us/projects/pex/molesmanual.pdf

(testo Chiave)

Moles può essere utilizzato per deviare qualsiasi metodo .NET, tra cui non virtuale e metodi statici in tipi sigillati.

Come funziona: Supponiamo di avere una situazione tipica del genere:

public static class SomeStaticClass 
{ 
    public static int SomeStaticMethod(string s) 
    { 
     return "Static method called: " + s; 
    } 
} 

public class SomeInstanceClass 
{ 
    public string SomeInstanceMethod(string s) 
    { 
     return SomeStaticClass.SomeStaticMethod(s); 
    } 
} 

Utilizzando Moles, il codice di prova sarebbe simile a questa:

[TestMethod()] 
[HostType("Moles")] 
public void ShouldBeAbleToTestStaticMethod() 
{ 
    var instance = new SomeInstanceClass(); 
    var testValue = instance.SomeInstanceMethod("Some test string"); 
    SomeStaticClass.SomeStaticMethod = (s) => "Moled you! " + s; 
    Assert.That(testValue, Is.EqualTo("Moled you! Some test string"); // sorry, this has code smell, lol 
} 

Naturalmente è necessario impostare up Moles nel tuo progetto di test, quindi assicurati di cercarlo - molte risorse web per aiutarti a raggiungere la tua strada.

Alcuni post utile:

https://msdn.microsoft.com/en-us/library/ff798308.aspx

http://adventuresdotnet.blogspot.com/2011/03/mocking-static-methods-for-unit-testing.html

https://wannabeegeek.wordpress.com/2013/03/13/unit-testing-made-easy-with-moles-part-i/

+0

Penso che dovresti almeno mostrare del codice nella tua risposta per mostrare come Moles può aiutare l'unità a testare metodi statici invece di pubblicare semplicemente link a varie risorse. – rexcfnghk

+0

Buon punto, lo farà tra un'ora o così. – code4life

+1

Moles è ancora supportato/disponibile? Il sito sembra affermare che Fakes lo sostituirà, e il link ipotizzabile per il download mi indirizzerà solo verso un elenco in cui Moles non è presente. Forse ho perso il link per il download? –

Problemi correlati