it-swarm.com.de

Scheinbare statische Eigenschaft mit moq

Ich bin ziemlich neu mit moq . Ich bin daran interessiert, einen Unit-Testfall für HttpModule zu erstellen, und alles funktioniert gut, bis ich eine static-Eigenschaft wie folgt stoße 

this.applicationPath = (HttpRuntime.AppDomainAppVirtualPath.Length > 1) ? HttpRuntime.AppDomainAppVirtualPath : String.Empty;

Ich weiß nicht, wie Mocks für static Klasse und Eigenschaften wie HttpRuntime.AppDomainAppVirtualPath erstellt werden. Die Variablen context, request und response wurden gut mit Beispielcode verspottet, den ich von moq bekomme. Ich werde es schätzen, wenn mir jemand dabei helfen kann.

41
jyothish george

Moq kann keine statischen Mitglieder fälschen.

Als Lösung können Sie eine Wrapper-Klasse (Adapter Pattern) erstellen, die die statische Eigenschaft enthält, und deren Member fälschen.
Zum Beispiel:

public class HttpRuntimeWrapper
{
    public virtual string AppDomainAppVirtualPath 
    { 
        get
        { 
            return HttpRuntime.AppDomainAppVirtualPath; 
        }
    }
}

Im Produktionscode können Sie anstelle von HttpRuntime auf diese Klasse zugreifen und diese Eigenschaft vortäuschen:

[Test]
public void AppDomainAppVirtualPathTest()
{
    var mock = new Moq.Mock<HttpRuntimeWrapper>();
    mock.Setup(fake => fake.AppDomainAppVirtualPath).Returns("FakedPath");

    Assert.AreEqual("FakedPath", mock.Object.AppDomainAppVirtualPath);
}

Eine andere Lösung ist die Verwendung des Isolationsframeworks (als Typemock Isolator ), in dem statische Klassen und Member gefälscht werden können.
Zum Beispiel:

Isolate.WhenCalled(() => HttpRuntime.AppDomainAppVirtualPath)
       .WillReturn("FakedPath");

Disclaimer - Ich arbeite bei Typemock

60
Elisha

Sie können keine statischen Methoden mit Moq verwenden.

Das ist in der Realität keine schlechte Sache, statische Methoden und Klassen haben ihren Platz, aber für die Logik machen sie das Testen von Einheiten schwierig. Natürlich stoßen Sie darauf, wenn Sie andere Bibliotheken verwenden. Um dies zu umgehen, müssen Sie einen Adapter (Wrapper) um den statischen Code schreiben und eine Schnittstelle bereitstellen. Zum Beispiel:

// Your static class - hard to mock
class StaticClass
{
   public static int ReturnOne() 
   {
       return 1;
   }
}

// Interface that you'll use for a wrapper
interface IStatic
{
    int ReturnOne();
}

Anmerkung, ich habe die konkrete Klasse, die IStatic für den Produktionscode verwendet, ausgelassen. Allit wäre eine Klasse, die IStatic verwendet, und Ihr Produktionscode würde diese Klasse anstelle von StaticClass verwenden.

Dann mit Moq:

var staticMock = new Mock<IStatic>();
staticMock.Setup(s => s.ReturnOne()).Returns(2);
11
Finglas

Wie in den vorigen Antworten erwähnt, können Sie MoQ nicht für statische Methoden verwenden. Wenn Sie dies tun müssen, sollten Sie einen Wrapper für die statische Klasse erstellen.

In letzter Zeit habe ich jedoch das Moles-Projekt entdeckt. Von der Homepage; "Mit Moles können Sie jede .NET-Methode durch einen Delegaten ersetzen. Moles unterstützt statische oder nicht virtuelle Methoden." Es könnte für Ihre aktuelle Situation nützlich sein.

3
Kirschstein

Beste Lösung, die ich bisher gefunden habe, ist Teleriks JustMock - leider erlaubt nur die kostenpflichtige Version die Statik zu verspotten. 

Die Idee, Statik zu verpacken, ist gut - Sie können das nicht immer tun. Wenn Sie Code testen möchten, der bereits statische Klassen verwendet, ist es nicht immer möglich, einen Wrapper auszutauschen. In diesem Fall scheint JustMock eine vernünftige Lösung zu sein, und ich werde es in naher Zukunft wahrscheinlich für einige Lösungen verwenden.

2
Ian

Sie können dazu Microsoft Fakes verwenden. Es wird definitiv das Problem lösen. Siehe https://msdn.Microsoft.com/de-de/library/hh549175.aspx

1
Sujith

Die Verwendung von Microsoft Fakes , wie von @Sujith vorgeschlagen, ist eine praktikable Lösung. So machen Sie es tatsächlich:

  • Suchen Sie System.Web in Ihrer Referenz Ihres Testprojekts und klicken Sie mit der rechten Maustaste
  • Wählen Sie "Hinzufügen". Dies fügt die Referenz System.Web.4.0.0.0.Fakes hinzu.
  • Verwenden Sie folgenden Code:

    using (Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create ()) { System.Web.Fakes.ShimHttpRuntime.AppDomainAppVirtualPathGet = () => "/"; // Erledige die gefälschte AppDomainAppVirtualPath }

0
Jack Miller