2017-01-12 3 views
1

Ich habe den folgenden (vereinfachten) Code.Nunit Test mit Mock. Instanz der Schnittstelle

public class Controller 
{ 
    private readonly IService _service; 

    public Controller(IService service) 
    { 
     _service = service; 
    } 

    public async Task<IHttpActionResult> Create(MyObject object) 
    { 
     var result = _service.method(object); 
     if (!result.Succeeded) 
     { 
      return this.GetErrorResult(object); 
     } 
    } 
} 

und SimpleInjector verwendet wird, um die Abhängigkeit zwischen _service und seiner Implementierungsklasse zu injizieren, wie folgt aus:

public static void Register(Container container) 
{ 
    container.Register<IService, Service>(); 
} 

Als Hinweis, Injektions- und Unit-Tests sind neu für mich so tun vollständig ich nicht verstehen sie, aber ich lerne.

Wenn ich die Anwendung über Swagger ausführen, funktioniert alles gut.

Als eine Anmerkung wird die Register Funktion aufgerufen, wenn ich die Anwendung über Swagger ausführen.

Nun, ich versuche, einige Unit-Tests einrichten NUnit verwenden und bin Mocking die IService Objekt wie folgt:

var Service = new Mock<IService>(); 
Controller _controller = new Controller(Service.Object); 
_controller.Create(new MyObject object()); 

die bisher mir richtig zu sein scheint - obwohl ich nicht sicher bin?

Das Problem ist, dass für den Komponententest result immer Null ist - ich denke, das ist, weil es ein Problem mit meinem Mock der Schnittstelle gibt - es scheint nicht die Methode zu finden - es tritt nie hinein und wird im Debugger nicht angezeigt.

Als Hinweis, für den Komponententest wird die Register Methode nicht aufgerufen. Ich habe versucht, es aufzurufen, um die Abhängigkeit zu registrieren, aber es hilft nicht.

Wie ich oben sagte, ist dies alles neu für mich und ich bin auf dem besten Stand meines Verständnisses zu all dem.

Ich habe keine Ideen mehr und weiß nicht, wo ich von hier aus suchen soll, also würde jede Hilfe sehr geschätzt werden.

EDIT:

Die ursprüngliche Frage war folgende:

public async Task<IHttpActionResult> Create(string content) 

, die ich aktualisiert:

public async Task<IHttpActionResult> Create(MyObject object) 

beraten Kann jemand, wie ich in einem allgemeinen Verweis auf MyObject passieren kann auf dem Setup, ohne eine Instanz dieser Klasse zu erstellen.

Also im Grunde möchte ich sagen, dass eine Instanz dieser Klasse übergeben wird, ohne diese Instanz zu erstellen.

Ich habe versucht, die folgenden:

Service.Setup(x => x.method(It.IsAny<MyObject>()) 

but it says cannot convert MethodGroup to MyObject 

und hier ist die Definition von IService:

public interface IService 
{ 
     IdentityResult method(ApplicationUser user, UserLoginInfo login); 
} 
+1

Rechts. Sie müssen den Mock einrichten, um das zu tun, was Sie für den Test tun möchten. Schauen Sie sich den schnellen Start hier https://github.com/Moq/moq4/wiki/Quickstart – Nkosi

+0

Haben Sie eine Mock-Setup auf dem Mock-Objekt? – ganeshran

+1

@Alex, Sie müssen möglicherweise das vereinfachte Beispiel ablegen und genau fragen, was Sie brauchen. Weil wir nur raten werden. Es sieht so aus, als ob Sie mit dem Asp.Net Identity-Framework arbeiten, das breit ist. Bitte beschränken Sie sich auf Details – Nkosi

Antwort

2

Sie müssen die Mock Objekt konfigurieren etwas für IService.method zurückzukehren wie folgt:

var Service = new Mock<IService>(); 
Service.Setup(x => x.method(It.IsAny<string>()) 
    .Returns<string>(str => **whatever result you need**); 

Mit dem Zusatz von Ihrer tatsächlichen IService Definition, sollten Sie den Setup Aufruf ändern:

Service.Setup(x => x.method(It.IsAny<ApplicationUser>(), It.IsAny<UserLoginInfo>()) 
    .Returns<ApplicationUser, UserLoginInfo>((user, login) => new IdentityResult(true)); 
+0

@chrisePickford können Sie mir bei der Bearbeitung helfen? – Alex

+1

Bitte fügen Sie Ihrer Frage die Definition von 'IService' hinzu. –

+0

Ich habe die IService Definition – Alex

3

Das Setup-Verfahren hat auf dem Mock-Objekt aufgerufen werden.

var Service = new Mock<IService>(); 
Service.Setup(x=>x.method("argument")).Returns(YourReturnObject) 
Controller _controller = new Controller(Service.Object); 
+0

können Sie mir bei der Bearbeitung helfen? – Alex

2

Verwenden Sie Ihr vereinfachtes Beispiel

public class Controller 
{ 
    private readonly IService _service; 

    public Controller(IService service) 
    { 
     _service = service; 
    } 

    public async Task<IHttpActionResult> Create(string content) 
    { 
     var result = await _service.method(content); 
     if (!result.Succeeded) 
     { 
      return this.GetErrorResult(result); 
     } 
     return Ok(); 
    } 
} 

Nehmen wir an, IService ist definiert als

public interface IService { 
    Task<Result> method(string input); 
} 

public class Result { 
    public bool Succeeded { get; set; } 
} 

Für das Gerät zu testen Sie die Mock zu fälschen einrichten müssen die Aktionen für den Test

public async Task Controller_Given_Content_Should_Return_Ok() { 
    //Arrange 
    var input = "content"; 
    var mockService = new Mock<IService>(); 
    mockService 
     .Setup(m => m.method(input)) 
     .ReturnAsync(new Result { Succeeded = true }); 
    var _controller = new Controller(mockService.Object); 

    //Act 
    var result = await _controller.Create(input); 

    //Assert 
    Assert.IsNotNull(result); 
    Assert.IsInstanceOfType(result,typeof(OkResult)); 
} 

Da das Verfahren im Test wollte, ist asynchron möchten Sie den Test auch so einrichten, dass er asynchron ist.

+0

können Sie mir bei der Bearbeitung helfen? – Alex