webentwicklung-frage-antwort-db.com.de

Verspotten Sie HttpRequest in ASP.NET Core Controller

Ich erstelle eine Web-API in ASP.NET Core und möchte die Controller in einem Stück testen.

Ich füge eine Schnittstelle für den Datenzugriff ein, die ich leicht verspotten kann. Der Controller muss jedoch die Header in der Anforderung nach einem Token überprüfen, und diese Anforderung scheint nicht zu existieren, wenn ich den Controller einfach selbst instanziiere, und sie ist auch nur für das Abrufen bestimmt, sodass ich sie nicht einmal manuell festlegen kann. Ich habe viele Beispiele gefunden, um einen ApiController zu verspotten, aber das ist kein .NET-Kern. Auch viele Tutorials und Beispiele zum Unit-Test von .net-Core-Controllern.

Ich habe ein MCVE gebaut, um dies zu demonstrieren:

[Produces("application/json")]
[Route("api/Players")]
public class PlayersController : Controller
{
    private IAccessor accessor;

    public PlayersController(IAccessor ac = null):base()
    {
        accessor = ac ?? AccessorFactory.GetAccessor();
    }

    /// <summary>
    /// Get all players. Must be logged in.
    /// </summary>
    /// <returns>Ok or Unauthorized.</returns>
    [HttpGet]
    public IActionResult Get()
    {
        Player client = accessor.GetLoggedInPlayer(Request.Headers["token"]); // NRE here because Request is null
        if (client == null) return Unauthorized();
        return Ok(accessor.GetAllPlayers());

    }
}    

Ich verwende Moq und MSTest in meinem Testprojekt und injiziere einen verspotteten IAccessor. Wie füge ich die Anfrage ein oder initialisiere sie mit dem Controller? Ich denke, mein letzter Ausweg wäre das Nachdenken, aber das möchte ich unbedingt vermeiden.

13
Squirrelkiller

Stellen Sie beim Erstellen einer Instanz des zu testenden Controllers sicher, dass Sie ein HttpContext zuweisen, das die erforderlichen Abhängigkeiten enthält, damit der Test vollständig ausgeführt werden kann.

Sie können versuchen, ein HttpContext zu verspotten und dies dem Controller zur Verfügung zu stellen, oder einfach das vom Framework bereitgestellte DefaultHttpContext verwenden

//Arrange
var mockedAccessor = new Mock<IAccessor>();
//...setup mockedAccessor behavior

//...

var httpContext = new DefaultHttpContext(); // or mock a `HttpContext`
httpContext.Request.Headers["token"] = "fake_token_here"; //Set header
 //Controller needs a controller context 
var controllerContext = new ControllerContext() {
    HttpContext = httpContext,
};
//assign context to controller
var controller = new PlayersController (mockedAccessor.Object){
    ControllerContext = controllerContext,
};

//Act
var result = controller.Get();

//...

Das oben Gesagte setzt voraus, dass Sie bereits wissen, wie man die Controller-Abhängigkeiten wie IAccessor verspottet, und demonstrieren sollten, wie Sie die für den Test erforderlichen Framework-spezifischen Abhängigkeiten bereitstellen.

18
Nkosi