Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Készítette: Steve Smith
Az egységtesztek magukban foglalják az alkalmazások egy részének tesztelését az infrastruktúrától és a függőségektől elkülönítve. Az egységtesztelési vezérlő logikája esetén a rendszer csak egyetlen művelet tartalmát teszteli, nem pedig a függőségek vagy maga a keretrendszer viselkedését.
Egységtesztelési vezérlők
Állítsa be a vezérlőműveletek egységtesztjeit, hogy a vezérlő viselkedésére összpontosítson. A vezérlőegység-teszt elkerüli az olyan forgatókönyveket, mint a szűrők, az útválasztás és a modellkötés. A kérelmekre együttesen válaszoló összetevők közötti interakciókat lefedő teszteket integrációs tesztek kezelik. Az integrációs tesztekkel kapcsolatos további információkért lásd az integrációs teszteket a ASP.NET Core-ban.
Ha egyéni szűrőket és útvonalakat ír, az egységek külön tesztelik őket, nem pedig egy adott vezérlőművelet tesztjeinek részeként.
A vezérlőegység-tesztek bemutatásához tekintse át az alábbi vezérlőt a mintaalkalmazásban.
Mintakód megtekintése vagy letöltése (hogyan töltsd le)
A Home vezérlő megjeleníti az ötletgyűjtési munkamenetek listáját, és lehetővé teszi új ötletgyűjtési munkamenetek létrehozását POST-kéréssel:
public class HomeController : Controller
{
private readonly IBrainstormSessionRepository _sessionRepository;
public HomeController(IBrainstormSessionRepository sessionRepository)
{
_sessionRepository = sessionRepository;
}
public async Task<IActionResult> Index()
{
var sessionList = await _sessionRepository.ListAsync();
var model = sessionList.Select(session => new StormSessionViewModel()
{
Id = session.Id,
DateCreated = session.DateCreated,
Name = session.Name,
IdeaCount = session.Ideas.Count
});
return View(model);
}
public class NewSessionModel
{
[Required]
public string SessionName { get; set; }
}
[HttpPost]
public async Task<IActionResult> Index(NewSessionModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
else
{
await _sessionRepository.AddAsync(new BrainstormSession()
{
DateCreated = DateTimeOffset.Now,
Name = model.SessionName
});
}
return RedirectToAction(actionName: nameof(Index));
}
}
Az előző vezérlő:
- Az explicit függőségek elvét követi.
- A függőséginjektálástól (DI) elvárja, hogy egy példányt biztosítson
IBrainstormSessionRepositoryból. - Mockolt
IBrainstormSessionRepositoryszolgáltatással tesztelhető makettobjektum-keretrendszerrel, például Moq. A mock objektum egy olyan létrehozott objektum, amelynek előre meghatározott tulajdonságai és metódusviselkedései vannak a teszteléshez. További információ: Bevezetés az integrációs tesztekbe.
A HTTP GET Index metódus nem rendelkezik hurkolással vagy elágaztatással, és csak egy metódust hív meg. A művelet egységtesztje:
- A
IBrainstormSessionRepositorymódszer használatával szimulálja aGetTestSessionsszolgáltatást.GetTestSessionskét makett ötletgyűjtési munkamenetet hoz létre dátumokkal és munkamenetnevekkel. - Végrehajtja a metódust
Index. - A metódus által visszaadott eredményre vonatkozó állításokat tesz:
- Visszaadódik egy ViewResult.
- A ViewDataDictionary.Model egy
StormSessionViewModel. - Két ötletgyűjtési munkamenet van tárolva a
ViewDataDictionary.Model.
[Fact]
public async Task Index_ReturnsAViewResult_WithAListOfBrainstormSessions()
{
// Arrange
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.ListAsync())
.ReturnsAsync(GetTestSessions());
var controller = new HomeController(mockRepo.Object);
// Act
var result = await controller.Index();
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
var model = Assert.IsAssignableFrom<IEnumerable<StormSessionViewModel>>(
viewResult.ViewData.Model);
Assert.Equal(2, model.Count());
}
private List<BrainstormSession> GetTestSessions()
{
var sessions = new List<BrainstormSession>();
sessions.Add(new BrainstormSession()
{
DateCreated = new DateTime(2016, 7, 2),
Id = 1,
Name = "Test One"
});
sessions.Add(new BrainstormSession()
{
DateCreated = new DateTime(2016, 7, 1),
Id = 2,
Name = "Test Two"
});
return sessions;
}
A Home vezérlő metódustesztjei HTTP POST Index ellenőrzik, hogy:
- Ha a ModelState.IsValid értéke,
falsea műveletmetódus egy 400 hibás kéréstViewResult ad vissza a megfelelő adatokkal. - Amikor
ModelState.IsValidtrue:- A
Addmetódus megvan hívva az adattáron. - A RedirectToActionResult a megfelelő argumentumokkal kerül visszaadásra.
- A
Az érvénytelen modellállapotokat az alábbi első tesztben látható hibák hozzáadásával AddModelError teszteljük:
[Fact]
public async Task IndexPost_ReturnsBadRequestResult_WhenModelStateIsInvalid()
{
// Arrange
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.ListAsync())
.ReturnsAsync(GetTestSessions());
var controller = new HomeController(mockRepo.Object);
controller.ModelState.AddModelError("SessionName", "Required");
var newSession = new HomeController.NewSessionModel();
// Act
var result = await controller.Index(newSession);
// Assert
var badRequestResult = Assert.IsType<BadRequestObjectResult>(result);
Assert.IsType<SerializableError>(badRequestResult.Value);
}
[Fact]
public async Task IndexPost_ReturnsARedirectAndAddsSession_WhenModelStateIsValid()
{
// Arrange
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.AddAsync(It.IsAny<BrainstormSession>()))
.Returns(Task.CompletedTask)
.Verifiable();
var controller = new HomeController(mockRepo.Object);
var newSession = new HomeController.NewSessionModel()
{
SessionName = "Test Name"
};
// Act
var result = await controller.Index(newSession);
// Assert
var redirectToActionResult = Assert.IsType<RedirectToActionResult>(result);
Assert.Null(redirectToActionResult.ControllerName);
Assert.Equal("Index", redirectToActionResult.ActionName);
mockRepo.Verify();
}
Ha a ModelState érvénytelen, ugyanaz ViewResult lesz visszaadva, mint egy GET-kérés esetében. A teszt nem próbál meg érvénytelen modellt átadni. Érvénytelen modell átadása nem érvényes módszer, mivel a modellkötés nem fut (bár egy integrációs teszt modellkötést használ). Ebben az esetben a modellkötés nincs tesztelve. Ezek az egységtesztek csak a műveletmetódusban tesztelik a kódot.
A második teszt ellenőrzi, hogy amikor érvényes a ModelState,
- Új
BrainstormSessionkerül hozzáadásra (az adattáron keresztül). - A metódus a
RedirectToActionResultvárt tulajdonságokat adja vissza.
A nem hívott mock hívásokat általában figyelmen kívül hagyják, de a beállítás végén végrehajtott hívás Verifiable lehetővé teszi a mock érvényesítését a tesztben. Ez a mockRepo.Verify hívásával történik, amely megbuktatja a tesztet, ha a várt metódust nem hívják meg.
Note
Az ebben a mintában használt Moq könyvtár lehetővé teszi az ellenőrizhető vagy "szigorú" mockok és nem ellenőrizhető mockok, más néven "laza" mockok vagy csonkok, kombinációját. További információ a Mock viselkedésének a Moq használatával történő testreszabásáról.
A mintaalkalmazás SessionControllerje egy adott ötletgyűjtési munkamenettel kapcsolatos információkat jelenít meg. A vezérlő az érvénytelen id értékek kezelésére szolgáló logikát tartalmaz (az alábbi példában két return forgatókönyv foglalkozik ezekkel a forgatókönyvekkel). A végső return utasítás egy új StormSessionViewModel nézetet ad vissza (Controllers/SessionController.cs):
public class SessionController : Controller
{
private readonly IBrainstormSessionRepository _sessionRepository;
public SessionController(IBrainstormSessionRepository sessionRepository)
{
_sessionRepository = sessionRepository;
}
public async Task<IActionResult> Index(int? id)
{
if (!id.HasValue)
{
return RedirectToAction(actionName: nameof(Index),
controllerName: "Home");
}
var session = await _sessionRepository.GetByIdAsync(id.Value);
if (session == null)
{
return Content("Session not found.");
}
var viewModel = new StormSessionViewModel()
{
DateCreated = session.DateCreated,
Name = session.Name,
Id = session.Id
};
return View(viewModel);
}
}
Az egységtesztek egy tesztet tartalmaznak a munkamenet-vezérlő return művelet minden Index egyes forgatókönyvéhez:
[Fact]
public async Task IndexReturnsARedirectToIndexHomeWhenIdIsNull()
{
// Arrange
var controller = new SessionController(sessionRepository: null);
// Act
var result = await controller.Index(id: null);
// Assert
var redirectToActionResult =
Assert.IsType<RedirectToActionResult>(result);
Assert.Equal("Home", redirectToActionResult.ControllerName);
Assert.Equal("Index", redirectToActionResult.ActionName);
}
[Fact]
public async Task IndexReturnsContentWithSessionNotFoundWhenSessionNotFound()
{
// Arrange
int testSessionId = 1;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync((BrainstormSession)null);
var controller = new SessionController(mockRepo.Object);
// Act
var result = await controller.Index(testSessionId);
// Assert
var contentResult = Assert.IsType<ContentResult>(result);
Assert.Equal("Session not found.", contentResult.Content);
}
[Fact]
public async Task IndexReturnsViewResultWithStormSessionViewModel()
{
// Arrange
int testSessionId = 1;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(GetTestSessions().FirstOrDefault(
s => s.Id == testSessionId));
var controller = new SessionController(mockRepo.Object);
// Act
var result = await controller.Index(testSessionId);
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
var model = Assert.IsType<StormSessionViewModel>(
viewResult.ViewData.Model);
Assert.Equal("Test One", model.Name);
Assert.Equal(2, model.DateCreated.Day);
Assert.Equal(testSessionId, model.Id);
}
Az Ötletek vezérlőre lépve az alkalmazás webes API-ként teszi elérhetővé a funkciókat az api/ideas útvonalon:
- A
IdeaDTOötletgyűjtési munkamenethez társított ötletek listáját aForSessionmetódus adja vissza. - A
Createmetódus új ötleteket ad hozzá egy munkamenethez.
[HttpGet("forsession/{sessionId}")]
public async Task<IActionResult> ForSession(int sessionId)
{
var session = await _sessionRepository.GetByIdAsync(sessionId);
if (session == null)
{
return NotFound(sessionId);
}
var result = session.Ideas.Select(idea => new IdeaDTO()
{
Id = idea.Id,
Name = idea.Name,
Description = idea.Description,
DateCreated = idea.DateCreated
}).ToList();
return Ok(result);
}
[HttpPost("create")]
public async Task<IActionResult> Create([FromBody]NewIdeaModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var session = await _sessionRepository.GetByIdAsync(model.SessionId);
if (session == null)
{
return NotFound(model.SessionId);
}
var idea = new Idea()
{
DateCreated = DateTimeOffset.Now,
Description = model.Description,
Name = model.Name
};
session.AddIdea(idea);
await _sessionRepository.UpdateAsync(session);
return Ok(session);
}
Kerülje az üzleti tartományentitások közvetlen visszaadását API-hívásokon keresztül. Tartományi entitások:
- Gyakran több adatot tartalmaz, mint amennyit az ügyfél igényel.
- Szükségtelenül párosítja az alkalmazás belső tartománymodelljét a nyilvánosan közzétett API-val.
A tartományentitások és az ügyfélnek visszaadott típusok közötti megfeleltetés elvégezhető:
- A mintaalkalmazás által használt LINQ-val
Selectmanuálisan. További információ: LINQ (Language Integrated Query). - Automatikusan egy tárral, például az AutoMapperrel.
A mintaalkalmazás ezután az Ötletek vezérlő API-módszereként a Create és ForSession egységteszteket demonstrálja.
A mintaalkalmazás két ForSession tesztet tartalmaz. Az első teszt azt vizsgálja, hogy ForSession egy érvénytelen munkamenet esetén NotFoundObjectResult-t (HTTP Nem található) ad-e vissza.
[Fact]
public async Task ForSession_ReturnsHttpNotFound_ForInvalidSession()
{
// Arrange
int testSessionId = 123;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync((BrainstormSession)null);
var controller = new IdeasController(mockRepo.Object);
// Act
var result = await controller.ForSession(testSessionId);
// Assert
var notFoundObjectResult = Assert.IsType<NotFoundObjectResult>(result);
Assert.Equal(testSessionId, notFoundObjectResult.Value);
}
A második ForSession teszt megállapítja, hogy a munkamenet-ötletek (ForSession) listáját adja-e <List<IdeaDTO>> vissza egy érvényes munkamenethez. Az ellenőrzések azt vizsgálják, hogy az első gondolat Name tulajdonsága helyes-e.
[Fact]
public async Task ForSession_ReturnsIdeasForSession()
{
// Arrange
int testSessionId = 123;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(GetTestSession());
var controller = new IdeasController(mockRepo.Object);
// Act
var result = await controller.ForSession(testSessionId);
// Assert
var okResult = Assert.IsType<OkObjectResult>(result);
var returnValue = Assert.IsType<List<IdeaDTO>>(okResult.Value);
var idea = returnValue.FirstOrDefault();
Assert.Equal("One", idea.Name);
}
A metódus viselkedésének Create teszteléséhez, ha az ModelState érvénytelen, a mintaalkalmazás modellhibát ad hozzá a vezérlőhöz a teszt részeként. Ne próbálja tesztelni a modellérvényesítést vagy a modellkötést az egységtesztekben – csak az akciómetódus viselkedését tesztelje, amikor érvénytelen ModelState-vel kerül szembe.
[Fact]
public async Task Create_ReturnsBadRequest_GivenInvalidModel()
{
// Arrange & Act
var mockRepo = new Mock<IBrainstormSessionRepository>();
var controller = new IdeasController(mockRepo.Object);
controller.ModelState.AddModelError("error", "some error");
// Act
var result = await controller.Create(model: null);
// Assert
Assert.IsType<BadRequestObjectResult>(result);
}
A második teszt attól függ, hogy az adattár visszaad-e Create, ezért az ál-adattár úgy van konfigurálva, hogy null-t adjon vissza. Nincs szükség tesztadatbázis létrehozására (a memóriában vagy más módon), és olyan lekérdezést létrehozni, amely ezt az eredményt adja vissza. A teszt egyetlen utasításban is elvégezhető, ahogy a mintakód is szemlélteti:
[Fact]
public async Task Create_ReturnsHttpNotFound_ForInvalidSession()
{
// Arrange
int testSessionId = 123;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync((BrainstormSession)null);
var controller = new IdeasController(mockRepo.Object);
// Act
var result = await controller.Create(new NewIdeaModel());
// Assert
Assert.IsType<NotFoundObjectResult>(result);
}
A harmadik Create teszt ellenőrzi, Create_ReturnsNewlyCreatedIdeaForSessionhogy az adattár metódusa UpdateAsync meghívva van-e. A makett Verifiable-val van meghívva, és a szimulált adattár Verify metódusa kerül meghívásra, hogy megerősítse az ellenőrizhető metódus végrehajtását. Nem az egységteszt feladata annak biztosítása, hogy a UpdateAsync metódus mentette az adatokat– ez egy integrációs teszttel végrehajtható.
[Fact]
public async Task Create_ReturnsNewlyCreatedIdeaForSession()
{
// Arrange
int testSessionId = 123;
string testName = "test name";
string testDescription = "test description";
var testSession = GetTestSession();
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(testSession);
var controller = new IdeasController(mockRepo.Object);
var newIdea = new NewIdeaModel()
{
Description = testDescription,
Name = testName,
SessionId = testSessionId
};
mockRepo.Setup(repo => repo.UpdateAsync(testSession))
.Returns(Task.CompletedTask)
.Verifiable();
// Act
var result = await controller.Create(newIdea);
// Assert
var okResult = Assert.IsType<OkObjectResult>(result);
var returnSession = Assert.IsType<BrainstormSession>(okResult.Value);
mockRepo.Verify();
Assert.Equal(2, returnSession.Ideas.Count());
Assert.Equal(testName, returnSession.Ideas.LastOrDefault().Name);
Assert.Equal(testDescription, returnSession.Ideas.LastOrDefault().Description);
}
ActionResult<T> tesztelése
ActionResult<T> (ActionResult<TValue>) visszaadhat egy ActionResult-ből származtatott típust vagy egy konkrét típust.
A mintaalkalmazás tartalmaz egy metódust, amely egy adott munkamenethez List<IdeaDTO>ad vissza egy id értéket. Ha a munkamenet id nem létezik, a vezérlő a következőt adja NotFoundvissza:
[HttpGet("forsessionactionresult/{sessionId}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public async Task<ActionResult<List<IdeaDTO>>> ForSessionActionResult(int sessionId)
{
var session = await _sessionRepository.GetByIdAsync(sessionId);
if (session == null)
{
return NotFound(sessionId);
}
var result = session.Ideas.Select(idea => new IdeaDTO()
{
Id = idea.Id,
Name = idea.Name,
Description = idea.Description,
DateCreated = idea.DateCreated
}).ToList();
return result;
}
A vezérlő két tesztje ForSessionActionResult szerepel a ApiIdeasControllerTests.
Az első teszt megerősíti, hogy a vezérlő visszaad egy ActionResult, de nem egy nem létező ötletlistát egy nem létező munkamenethez id.
- A
ActionResulttípus a következőActionResult<List<IdeaDTO>>: . - Az Result egy NotFoundObjectResult.
[Fact]
public async Task ForSessionActionResult_ReturnsNotFoundObjectResultForNonexistentSession()
{
// Arrange
var mockRepo = new Mock<IBrainstormSessionRepository>();
var controller = new IdeasController(mockRepo.Object);
var nonExistentSessionId = 999;
// Act
var result = await controller.ForSessionActionResult(nonExistentSessionId);
// Assert
var actionResult = Assert.IsType<ActionResult<List<IdeaDTO>>>(result);
Assert.IsType<NotFoundObjectResult>(actionResult.Result);
}
Érvényes munkamenet idesetén a második teszt megerősíti, hogy a metódus a következőt adja vissza:
- Egy
ActionResultaList<IdeaDTO>típussal. - Az
ActionResult T .Value érték egy típus. - A lista első eleme egy érvényes ötlet, amely megfelel a mintamunkamenetben tárolt ötletnek (hívással
GetTestSessionszerezhető be).
[Fact]
public async Task ForSessionActionResult_ReturnsIdeasForSession()
{
// Arrange
int testSessionId = 123;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(GetTestSession());
var controller = new IdeasController(mockRepo.Object);
// Act
var result = await controller.ForSessionActionResult(testSessionId);
// Assert
var actionResult = Assert.IsType<ActionResult<List<IdeaDTO>>>(result);
var returnValue = Assert.IsType<List<IdeaDTO>>(actionResult.Value);
var idea = returnValue.FirstOrDefault();
Assert.Equal("One", idea.Name);
}
A mintaalkalmazás egy adott munkamenethez új Idea létrehozására szolgáló módszert is tartalmaz. A vezérlő a következőt adja vissza:
- BadRequest érvénytelen modell esetén.
- NotFound ha a munkamenet nem létezik.
- CreatedAtAction amikor a munkamenet az új ötlettel kerül frissítésre.
[HttpPost("createactionresult")]
[ProducesResponseType(201)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public async Task<ActionResult<BrainstormSession>> CreateActionResult([FromBody]NewIdeaModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var session = await _sessionRepository.GetByIdAsync(model.SessionId);
if (session == null)
{
return NotFound(model.SessionId);
}
var idea = new Idea()
{
DateCreated = DateTimeOffset.Now,
Description = model.Description,
Name = model.Name
};
session.AddIdea(idea);
await _sessionRepository.UpdateAsync(session);
return CreatedAtAction(nameof(CreateActionResult), new { id = session.Id }, session);
}
Három teszt CreateActionResult található a ApiIdeasControllerTests.
Az első szöveg megerősíti, hogy a BadRequest rendszer érvénytelen modellt ad vissza.
[Fact]
public async Task CreateActionResult_ReturnsBadRequest_GivenInvalidModel()
{
// Arrange & Act
var mockRepo = new Mock<IBrainstormSessionRepository>();
var controller = new IdeasController(mockRepo.Object);
controller.ModelState.AddModelError("error", "some error");
// Act
var result = await controller.CreateActionResult(model: null);
// Assert
var actionResult = Assert.IsType<ActionResult<BrainstormSession>>(result);
Assert.IsType<BadRequestObjectResult>(actionResult.Result);
}
A második teszt ellenőrzi, hogy egy NotFound kerül visszaadásra, ha a munkamenet nem létezik.
[Fact]
public async Task CreateActionResult_ReturnsNotFoundObjectResultForNonexistentSession()
{
// Arrange
var nonExistentSessionId = 999;
string testName = "test name";
string testDescription = "test description";
var mockRepo = new Mock<IBrainstormSessionRepository>();
var controller = new IdeasController(mockRepo.Object);
var newIdea = new NewIdeaModel()
{
Description = testDescription,
Name = testName,
SessionId = nonExistentSessionId
};
// Act
var result = await controller.CreateActionResult(newIdea);
// Assert
var actionResult = Assert.IsType<ActionResult<BrainstormSession>>(result);
Assert.IsType<NotFoundObjectResult>(actionResult.Result);
}
Érvényes munkamenet idesetén az utolsó teszt megerősíti, hogy:
- A metódus egy
ActionResulttípusúBrainstormSession-et ad vissza. - Az
ActionResult T .Result egy . CreatedAtActionResulthasonló a 201 Created válaszhoz egyLocationfejléccel. - Az
ActionResult T .Value érték egy típus. - Meghívták a munkamenet
UpdateAsync(testSession)frissítésére irányuló mintahívást. AVerifiablemetódushívás ellenőrzésemockRepo.Verify()végrehajtásával történik az állításokban. - A rendszer két
Ideaobjektumot ad vissza a munkamenethez. - Az utolsó elem (a
IdeamodellhívásUpdateAsyncáltal hozzáadott) megegyezik anewIdeateszt munkamenetéhez hozzáadott elemével.
[Fact]
public async Task CreateActionResult_ReturnsNewlyCreatedIdeaForSession()
{
// Arrange
int testSessionId = 123;
string testName = "test name";
string testDescription = "test description";
var testSession = GetTestSession();
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(testSession);
var controller = new IdeasController(mockRepo.Object);
var newIdea = new NewIdeaModel()
{
Description = testDescription,
Name = testName,
SessionId = testSessionId
};
mockRepo.Setup(repo => repo.UpdateAsync(testSession))
.Returns(Task.CompletedTask)
.Verifiable();
// Act
var result = await controller.CreateActionResult(newIdea);
// Assert
var actionResult = Assert.IsType<ActionResult<BrainstormSession>>(result);
var createdAtActionResult = Assert.IsType<CreatedAtActionResult>(actionResult.Result);
var returnValue = Assert.IsType<BrainstormSession>(createdAtActionResult.Value);
mockRepo.Verify();
Assert.Equal(2, returnValue.Ideas.Count());
Assert.Equal(testName, returnValue.Ideas.LastOrDefault().Name);
Assert.Equal(testDescription, returnValue.Ideas.LastOrDefault().Description);
}
A vezérlők központi szerepet játszanak minden ASP.NET Core MVC-alkalmazásban. Ezért biztosnak kell lennie abban, hogy a vezérlők a kívánt módon viselkednek. Az automatizált tesztek az alkalmazás éles környezetben való üzembe helyezése előtt észlelhetik a hibákat.
Mintakód megtekintése vagy letöltése (hogyan töltsd le)
Vezérlőlogika egységtesztjei
Az egységtesztek magukban foglalják az alkalmazások egy részének tesztelését az infrastruktúrától és a függőségektől elkülönítve. Az egységtesztelési vezérlő logikája esetén a rendszer csak egyetlen művelet tartalmát teszteli, nem pedig a függőségek vagy maga a keretrendszer viselkedését.
Állítsa be a vezérlőműveletek egységtesztjeit, hogy a vezérlő viselkedésére összpontosítson. A vezérlőegység-teszt elkerüli az olyan forgatókönyveket, mint a szűrők, az útválasztás és a modellkötés. A kérelmekre együttesen válaszoló összetevők közötti interakciókat lefedő teszteket integrációs tesztek kezelik. Az integrációs tesztekkel kapcsolatos további információkért lásd az integrációs teszteket a ASP.NET Core-ban.
Ha egyéni szűrőket és útvonalakat ír, az egységek külön tesztelik őket, nem pedig egy adott vezérlőművelet tesztjeinek részeként.
A vezérlőegység-tesztek bemutatásához tekintse át az alábbi vezérlőt a mintaalkalmazásban. A Home vezérlő megjeleníti az ötletgyűjtési munkamenetek listáját, és lehetővé teszi új ötletgyűjtési munkamenetek létrehozását POST-kéréssel:
public class HomeController : Controller
{
private readonly IBrainstormSessionRepository _sessionRepository;
public HomeController(IBrainstormSessionRepository sessionRepository)
{
_sessionRepository = sessionRepository;
}
public async Task<IActionResult> Index()
{
var sessionList = await _sessionRepository.ListAsync();
var model = sessionList.Select(session => new StormSessionViewModel()
{
Id = session.Id,
DateCreated = session.DateCreated,
Name = session.Name,
IdeaCount = session.Ideas.Count
});
return View(model);
}
public class NewSessionModel
{
[Required]
public string SessionName { get; set; }
}
[HttpPost]
public async Task<IActionResult> Index(NewSessionModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
else
{
await _sessionRepository.AddAsync(new BrainstormSession()
{
DateCreated = DateTimeOffset.Now,
Name = model.SessionName
});
}
return RedirectToAction(actionName: nameof(Index));
}
}
Az előző vezérlő:
- Az explicit függőségek elvét követi.
- A függőséginjektálástól (DI) elvárja, hogy egy példányt biztosítson
IBrainstormSessionRepositoryból. - Mockolt
IBrainstormSessionRepositoryszolgáltatással tesztelhető makettobjektum-keretrendszerrel, például Moq. A mock objektum egy olyan létrehozott objektum, amelynek előre meghatározott tulajdonságai és metódusviselkedései vannak a teszteléshez. További információ: Bevezetés az integrációs tesztekbe.
A HTTP GET Index metódus nem rendelkezik hurkolással vagy elágaztatással, és csak egy metódust hív meg. A művelet egységtesztje:
- A
IBrainstormSessionRepositorymódszer használatával szimulálja aGetTestSessionsszolgáltatást.GetTestSessionskét makett ötletgyűjtési munkamenetet hoz létre dátumokkal és munkamenetnevekkel. - Végrehajtja a metódust
Index. - A metódus által visszaadott eredményre vonatkozó állításokat tesz:
- Visszaadódik egy ViewResult.
- A ViewDataDictionary.Model egy
StormSessionViewModel. - Két ötletgyűjtési munkamenet van tárolva a
ViewDataDictionary.Model.
[Fact]
public async Task Index_ReturnsAViewResult_WithAListOfBrainstormSessions()
{
// Arrange
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.ListAsync())
.ReturnsAsync(GetTestSessions());
var controller = new HomeController(mockRepo.Object);
// Act
var result = await controller.Index();
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
var model = Assert.IsAssignableFrom<IEnumerable<StormSessionViewModel>>(
viewResult.ViewData.Model);
Assert.Equal(2, model.Count());
}
private List<BrainstormSession> GetTestSessions()
{
var sessions = new List<BrainstormSession>();
sessions.Add(new BrainstormSession()
{
DateCreated = new DateTime(2016, 7, 2),
Id = 1,
Name = "Test One"
});
sessions.Add(new BrainstormSession()
{
DateCreated = new DateTime(2016, 7, 1),
Id = 2,
Name = "Test Two"
});
return sessions;
}
A Home vezérlő metódustesztjei HTTP POST Index ellenőrzik, hogy:
- Ha a ModelState.IsValid értéke,
falsea műveletmetódus egy 400 hibás kéréstViewResult ad vissza a megfelelő adatokkal. - Amikor
ModelState.IsValidtrue:- A
Addmetódus megvan hívva az adattáron. - A RedirectToActionResult a megfelelő argumentumokkal kerül visszaadásra.
- A
Az érvénytelen modellállapotokat az alábbi első tesztben látható hibák hozzáadásával AddModelError teszteljük:
[Fact]
public async Task IndexPost_ReturnsBadRequestResult_WhenModelStateIsInvalid()
{
// Arrange
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.ListAsync())
.ReturnsAsync(GetTestSessions());
var controller = new HomeController(mockRepo.Object);
controller.ModelState.AddModelError("SessionName", "Required");
var newSession = new HomeController.NewSessionModel();
// Act
var result = await controller.Index(newSession);
// Assert
var badRequestResult = Assert.IsType<BadRequestObjectResult>(result);
Assert.IsType<SerializableError>(badRequestResult.Value);
}
[Fact]
public async Task IndexPost_ReturnsARedirectAndAddsSession_WhenModelStateIsValid()
{
// Arrange
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.AddAsync(It.IsAny<BrainstormSession>()))
.Returns(Task.CompletedTask)
.Verifiable();
var controller = new HomeController(mockRepo.Object);
var newSession = new HomeController.NewSessionModel()
{
SessionName = "Test Name"
};
// Act
var result = await controller.Index(newSession);
// Assert
var redirectToActionResult = Assert.IsType<RedirectToActionResult>(result);
Assert.Null(redirectToActionResult.ControllerName);
Assert.Equal("Index", redirectToActionResult.ActionName);
mockRepo.Verify();
}
Ha a ModelState érvénytelen, ugyanaz ViewResult lesz visszaadva, mint egy GET-kérés esetében. A teszt nem próbál meg érvénytelen modellt átadni. Érvénytelen modell átadása nem érvényes módszer, mivel a modellkötés nem fut (bár egy integrációs teszt modellkötést használ). Ebben az esetben a modellkötés nincs tesztelve. Ezek az egységtesztek csak a műveletmetódusban tesztelik a kódot.
A második teszt ellenőrzi, hogy amikor érvényes a ModelState,
- Új
BrainstormSessionkerül hozzáadásra (az adattáron keresztül). - A metódus a
RedirectToActionResultvárt tulajdonságokat adja vissza.
A nem hívott mock hívásokat általában figyelmen kívül hagyják, de a beállítás végén végrehajtott hívás Verifiable lehetővé teszi a mock érvényesítését a tesztben. Ez a mockRepo.Verify hívásával történik, amely megbuktatja a tesztet, ha a várt metódust nem hívják meg.
Note
Az ebben a mintában használt Moq könyvtár lehetővé teszi az ellenőrizhető vagy "szigorú" mockok és nem ellenőrizhető mockok, más néven "laza" mockok vagy csonkok, kombinációját. További információ a Mock viselkedésének a Moq használatával történő testreszabásáról.
A mintaalkalmazás SessionControllerje egy adott ötletgyűjtési munkamenettel kapcsolatos információkat jelenít meg. A vezérlő az érvénytelen id értékek kezelésére szolgáló logikát tartalmaz (az alábbi példában két return forgatókönyv foglalkozik ezekkel a forgatókönyvekkel). A végső return utasítás egy új StormSessionViewModel nézetet ad vissza (Controllers/SessionController.cs):
public class SessionController : Controller
{
private readonly IBrainstormSessionRepository _sessionRepository;
public SessionController(IBrainstormSessionRepository sessionRepository)
{
_sessionRepository = sessionRepository;
}
public async Task<IActionResult> Index(int? id)
{
if (!id.HasValue)
{
return RedirectToAction(actionName: nameof(Index),
controllerName: "Home");
}
var session = await _sessionRepository.GetByIdAsync(id.Value);
if (session == null)
{
return Content("Session not found.");
}
var viewModel = new StormSessionViewModel()
{
DateCreated = session.DateCreated,
Name = session.Name,
Id = session.Id
};
return View(viewModel);
}
}
Az egységtesztek egy tesztet tartalmaznak a munkamenet-vezérlő return művelet minden Index egyes forgatókönyvéhez:
[Fact]
public async Task IndexReturnsARedirectToIndexHomeWhenIdIsNull()
{
// Arrange
var controller = new SessionController(sessionRepository: null);
// Act
var result = await controller.Index(id: null);
// Assert
var redirectToActionResult =
Assert.IsType<RedirectToActionResult>(result);
Assert.Equal("Home", redirectToActionResult.ControllerName);
Assert.Equal("Index", redirectToActionResult.ActionName);
}
[Fact]
public async Task IndexReturnsContentWithSessionNotFoundWhenSessionNotFound()
{
// Arrange
int testSessionId = 1;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync((BrainstormSession)null);
var controller = new SessionController(mockRepo.Object);
// Act
var result = await controller.Index(testSessionId);
// Assert
var contentResult = Assert.IsType<ContentResult>(result);
Assert.Equal("Session not found.", contentResult.Content);
}
[Fact]
public async Task IndexReturnsViewResultWithStormSessionViewModel()
{
// Arrange
int testSessionId = 1;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(GetTestSessions().FirstOrDefault(
s => s.Id == testSessionId));
var controller = new SessionController(mockRepo.Object);
// Act
var result = await controller.Index(testSessionId);
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
var model = Assert.IsType<StormSessionViewModel>(
viewResult.ViewData.Model);
Assert.Equal("Test One", model.Name);
Assert.Equal(2, model.DateCreated.Day);
Assert.Equal(testSessionId, model.Id);
}
Az Ötletek vezérlőre lépve az alkalmazás webes API-ként teszi elérhetővé a funkciókat az api/ideas útvonalon:
- A
IdeaDTOötletgyűjtési munkamenethez társított ötletek listáját aForSessionmetódus adja vissza. - A
Createmetódus új ötleteket ad hozzá egy munkamenethez.
[HttpGet("forsession/{sessionId}")]
public async Task<IActionResult> ForSession(int sessionId)
{
var session = await _sessionRepository.GetByIdAsync(sessionId);
if (session == null)
{
return NotFound(sessionId);
}
var result = session.Ideas.Select(idea => new IdeaDTO()
{
Id = idea.Id,
Name = idea.Name,
Description = idea.Description,
DateCreated = idea.DateCreated
}).ToList();
return Ok(result);
}
[HttpPost("create")]
public async Task<IActionResult> Create([FromBody]NewIdeaModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var session = await _sessionRepository.GetByIdAsync(model.SessionId);
if (session == null)
{
return NotFound(model.SessionId);
}
var idea = new Idea()
{
DateCreated = DateTimeOffset.Now,
Description = model.Description,
Name = model.Name
};
session.AddIdea(idea);
await _sessionRepository.UpdateAsync(session);
return Ok(session);
}
Kerülje az üzleti tartományentitások közvetlen visszaadását API-hívásokon keresztül. Tartományi entitások:
- Gyakran több adatot tartalmaz, mint amennyit az ügyfél igényel.
- Szükségtelenül párosítja az alkalmazás belső tartománymodelljét a nyilvánosan közzétett API-val.
A tartományentitások és az ügyfélnek visszaadott típusok közötti megfeleltetés elvégezhető:
- A mintaalkalmazás által használt LINQ-val
Selectmanuálisan. További információ: LINQ (Language Integrated Query). - Automatikusan egy tárral, például az AutoMapperrel.
A mintaalkalmazás ezután az Ötletek vezérlő API-módszereként a Create és ForSession egységteszteket demonstrálja.
A mintaalkalmazás két ForSession tesztet tartalmaz. Az első teszt azt vizsgálja, hogy ForSession egy érvénytelen munkamenet esetén NotFoundObjectResult-t (HTTP Nem található) ad-e vissza.
[Fact]
public async Task ForSession_ReturnsHttpNotFound_ForInvalidSession()
{
// Arrange
int testSessionId = 123;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync((BrainstormSession)null);
var controller = new IdeasController(mockRepo.Object);
// Act
var result = await controller.ForSession(testSessionId);
// Assert
var notFoundObjectResult = Assert.IsType<NotFoundObjectResult>(result);
Assert.Equal(testSessionId, notFoundObjectResult.Value);
}
A második ForSession teszt megállapítja, hogy a munkamenet-ötletek (ForSession) listáját adja-e <List<IdeaDTO>> vissza egy érvényes munkamenethez. Az ellenőrzések azt vizsgálják, hogy az első gondolat Name tulajdonsága helyes-e.
[Fact]
public async Task ForSession_ReturnsIdeasForSession()
{
// Arrange
int testSessionId = 123;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(GetTestSession());
var controller = new IdeasController(mockRepo.Object);
// Act
var result = await controller.ForSession(testSessionId);
// Assert
var okResult = Assert.IsType<OkObjectResult>(result);
var returnValue = Assert.IsType<List<IdeaDTO>>(okResult.Value);
var idea = returnValue.FirstOrDefault();
Assert.Equal("One", idea.Name);
}
A metódus viselkedésének Create teszteléséhez, ha az ModelState érvénytelen, a mintaalkalmazás modellhibát ad hozzá a vezérlőhöz a teszt részeként. Ne próbálja tesztelni a modellérvényesítést vagy a modellkötést az egységtesztekben – csak az akciómetódus viselkedését tesztelje, amikor érvénytelen ModelState-vel kerül szembe.
[Fact]
public async Task Create_ReturnsBadRequest_GivenInvalidModel()
{
// Arrange & Act
var mockRepo = new Mock<IBrainstormSessionRepository>();
var controller = new IdeasController(mockRepo.Object);
controller.ModelState.AddModelError("error", "some error");
// Act
var result = await controller.Create(model: null);
// Assert
Assert.IsType<BadRequestObjectResult>(result);
}
A második teszt attól függ, hogy az adattár visszaad-e Create, ezért az ál-adattár úgy van konfigurálva, hogy null-t adjon vissza. Nincs szükség tesztadatbázis létrehozására (a memóriában vagy más módon), és olyan lekérdezést létrehozni, amely ezt az eredményt adja vissza. A teszt egyetlen utasításban is elvégezhető, ahogy a mintakód is szemlélteti:
[Fact]
public async Task Create_ReturnsHttpNotFound_ForInvalidSession()
{
// Arrange
int testSessionId = 123;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync((BrainstormSession)null);
var controller = new IdeasController(mockRepo.Object);
// Act
var result = await controller.Create(new NewIdeaModel());
// Assert
Assert.IsType<NotFoundObjectResult>(result);
}
A harmadik Create teszt ellenőrzi, Create_ReturnsNewlyCreatedIdeaForSessionhogy az adattár metódusa UpdateAsync meghívva van-e. A makett Verifiable-val van meghívva, és a szimulált adattár Verify metódusa kerül meghívásra, hogy megerősítse az ellenőrizhető metódus végrehajtását. Nem az egységteszt feladata annak biztosítása, hogy a UpdateAsync metódus mentette az adatokat– ez egy integrációs teszttel végrehajtható.
[Fact]
public async Task Create_ReturnsNewlyCreatedIdeaForSession()
{
// Arrange
int testSessionId = 123;
string testName = "test name";
string testDescription = "test description";
var testSession = GetTestSession();
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(testSession);
var controller = new IdeasController(mockRepo.Object);
var newIdea = new NewIdeaModel()
{
Description = testDescription,
Name = testName,
SessionId = testSessionId
};
mockRepo.Setup(repo => repo.UpdateAsync(testSession))
.Returns(Task.CompletedTask)
.Verifiable();
// Act
var result = await controller.Create(newIdea);
// Assert
var okResult = Assert.IsType<OkObjectResult>(result);
var returnSession = Assert.IsType<BrainstormSession>(okResult.Value);
mockRepo.Verify();
Assert.Equal(2, returnSession.Ideas.Count());
Assert.Equal(testName, returnSession.Ideas.LastOrDefault().Name);
Assert.Equal(testDescription, returnSession.Ideas.LastOrDefault().Description);
}
ActionResult<T> tesztelése
hu-HU: Az ASP.NET Core 2.1-es vagy újabb verziójában az ActionResult<T> (ActionResult<TValue>) lehetővé teszi, hogy visszaadjon egy olyan típust, amely ActionResult-ből származik, vagy egy konkrét típust adjon vissza.
A mintaalkalmazás tartalmaz egy metódust, amely egy adott munkamenethez List<IdeaDTO>ad vissza egy id értéket. Ha a munkamenet id nem létezik, a vezérlő a következőt adja NotFoundvissza:
[HttpGet("forsessionactionresult/{sessionId}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public async Task<ActionResult<List<IdeaDTO>>> ForSessionActionResult(int sessionId)
{
var session = await _sessionRepository.GetByIdAsync(sessionId);
if (session == null)
{
return NotFound(sessionId);
}
var result = session.Ideas.Select(idea => new IdeaDTO()
{
Id = idea.Id,
Name = idea.Name,
Description = idea.Description,
DateCreated = idea.DateCreated
}).ToList();
return result;
}
A vezérlő két tesztje ForSessionActionResult szerepel a ApiIdeasControllerTests.
Az első teszt megerősíti, hogy a vezérlő visszaad egy ActionResult, de nem egy nem létező ötletlistát egy nem létező munkamenethez id.
- A
ActionResulttípus a következőActionResult<List<IdeaDTO>>: . - Az Result egy NotFoundObjectResult.
[Fact]
public async Task ForSessionActionResult_ReturnsNotFoundObjectResultForNonexistentSession()
{
// Arrange
var mockRepo = new Mock<IBrainstormSessionRepository>();
var controller = new IdeasController(mockRepo.Object);
var nonExistentSessionId = 999;
// Act
var result = await controller.ForSessionActionResult(nonExistentSessionId);
// Assert
var actionResult = Assert.IsType<ActionResult<List<IdeaDTO>>>(result);
Assert.IsType<NotFoundObjectResult>(actionResult.Result);
}
Érvényes munkamenet idesetén a második teszt megerősíti, hogy a metódus a következőt adja vissza:
- Egy
ActionResultaList<IdeaDTO>típussal. - Az
ActionResult T .Value érték egy típus. - A lista első eleme egy érvényes ötlet, amely megfelel a mintamunkamenetben tárolt ötletnek (hívással
GetTestSessionszerezhető be).
[Fact]
public async Task ForSessionActionResult_ReturnsIdeasForSession()
{
// Arrange
int testSessionId = 123;
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(GetTestSession());
var controller = new IdeasController(mockRepo.Object);
// Act
var result = await controller.ForSessionActionResult(testSessionId);
// Assert
var actionResult = Assert.IsType<ActionResult<List<IdeaDTO>>>(result);
var returnValue = Assert.IsType<List<IdeaDTO>>(actionResult.Value);
var idea = returnValue.FirstOrDefault();
Assert.Equal("One", idea.Name);
}
A mintaalkalmazás egy adott munkamenethez új Idea létrehozására szolgáló módszert is tartalmaz. A vezérlő a következőt adja vissza:
- BadRequest érvénytelen modell esetén.
- NotFound ha a munkamenet nem létezik.
- CreatedAtAction amikor a munkamenet az új ötlettel kerül frissítésre.
[HttpPost("createactionresult")]
[ProducesResponseType(201)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public async Task<ActionResult<BrainstormSession>> CreateActionResult([FromBody]NewIdeaModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var session = await _sessionRepository.GetByIdAsync(model.SessionId);
if (session == null)
{
return NotFound(model.SessionId);
}
var idea = new Idea()
{
DateCreated = DateTimeOffset.Now,
Description = model.Description,
Name = model.Name
};
session.AddIdea(idea);
await _sessionRepository.UpdateAsync(session);
return CreatedAtAction(nameof(CreateActionResult), new { id = session.Id }, session);
}
Három teszt CreateActionResult található a ApiIdeasControllerTests.
Az első szöveg megerősíti, hogy a BadRequest rendszer érvénytelen modellt ad vissza.
[Fact]
public async Task CreateActionResult_ReturnsBadRequest_GivenInvalidModel()
{
// Arrange & Act
var mockRepo = new Mock<IBrainstormSessionRepository>();
var controller = new IdeasController(mockRepo.Object);
controller.ModelState.AddModelError("error", "some error");
// Act
var result = await controller.CreateActionResult(model: null);
// Assert
var actionResult = Assert.IsType<ActionResult<BrainstormSession>>(result);
Assert.IsType<BadRequestObjectResult>(actionResult.Result);
}
A második teszt ellenőrzi, hogy egy NotFound kerül visszaadásra, ha a munkamenet nem létezik.
[Fact]
public async Task CreateActionResult_ReturnsNotFoundObjectResultForNonexistentSession()
{
// Arrange
var nonExistentSessionId = 999;
string testName = "test name";
string testDescription = "test description";
var mockRepo = new Mock<IBrainstormSessionRepository>();
var controller = new IdeasController(mockRepo.Object);
var newIdea = new NewIdeaModel()
{
Description = testDescription,
Name = testName,
SessionId = nonExistentSessionId
};
// Act
var result = await controller.CreateActionResult(newIdea);
// Assert
var actionResult = Assert.IsType<ActionResult<BrainstormSession>>(result);
Assert.IsType<NotFoundObjectResult>(actionResult.Result);
}
Érvényes munkamenet idesetén az utolsó teszt megerősíti, hogy:
- A metódus egy
ActionResulttípusúBrainstormSession-et ad vissza. - Az
ActionResult T .Result egy . CreatedAtActionResulthasonló a 201 Created válaszhoz egyLocationfejléccel. - Az
ActionResult T .Value érték egy típus. - Meghívták a munkamenet
UpdateAsync(testSession)frissítésére irányuló mintahívást. AVerifiablemetódushívás ellenőrzésemockRepo.Verify()végrehajtásával történik az állításokban. - A rendszer két
Ideaobjektumot ad vissza a munkamenethez. - Az utolsó elem (a
IdeamodellhívásUpdateAsyncáltal hozzáadott) megegyezik anewIdeateszt munkamenetéhez hozzáadott elemével.
[Fact]
public async Task CreateActionResult_ReturnsNewlyCreatedIdeaForSession()
{
// Arrange
int testSessionId = 123;
string testName = "test name";
string testDescription = "test description";
var testSession = GetTestSession();
var mockRepo = new Mock<IBrainstormSessionRepository>();
mockRepo.Setup(repo => repo.GetByIdAsync(testSessionId))
.ReturnsAsync(testSession);
var controller = new IdeasController(mockRepo.Object);
var newIdea = new NewIdeaModel()
{
Description = testDescription,
Name = testName,
SessionId = testSessionId
};
mockRepo.Setup(repo => repo.UpdateAsync(testSession))
.Returns(Task.CompletedTask)
.Verifiable();
// Act
var result = await controller.CreateActionResult(newIdea);
// Assert
var actionResult = Assert.IsType<ActionResult<BrainstormSession>>(result);
var createdAtActionResult = Assert.IsType<CreatedAtActionResult>(actionResult.Result);
var returnValue = Assert.IsType<BrainstormSession>(createdAtActionResult.Value);
mockRepo.Verify();
Assert.Equal(2, returnValue.Ideas.Count());
Assert.Equal(testName, returnValue.Ideas.LastOrDefault().Name);
Assert.Equal(testDescription, returnValue.Ideas.LastOrDefault().Description);
}
További erőforrások
- Az integrációs tesztek az ASP.NET Core-ban
- Egységtesztek létrehozása és futtatása a Visual Studióval
- MyTested.AspNetCore.Mvc – Fluent Testing Library for ASP.NET Core MVC: Erősen gépelt egységtesztelési kódtár, amely folyékony felületet biztosít az MVC és a webes API-alkalmazások teszteléséhez. (A Microsoft nem tartja karban vagy nem támogatja.)
- JustMockLite: Egy csúfoló keretrendszer .NET-fejlesztők számára. (A Microsoft nem tartja karban vagy nem támogatja.)