Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Tarafından Steve Smith
Birim testleri , bir uygulamanın bir bölümünü altyapısından ve bağımlılıklarından yalıtılarak test etmeyi içerir. Birim testi denetleyicisi mantığı, bağımlılıklarının veya çerçevenin davranışını değil, yalnızca tek bir eylemin içeriğini test eder.
Birim testi denetleyicileri
Denetleyicinin davranışına odaklanmak için denetleyici eylemlerinin birim testlerini ayarlayın. Denetleyici birim testi filtreler, yönlendirme ve model bağlama gibi senaryoları önler. Bir isteğe toplu olarak yanıt veren bileşenler arasındaki etkileşimleri kapsayan testler tümleştirme testleri tarafından işlenir. Tümleştirme testleri hakkında daha fazla bilgi için bkz . ASP.NET Core'da tümleştirme testleri.
Özel filtreler ve yollar yazıyorsanız, birim testi bunları belirli bir denetleyici eylemindeki testlerin parçası olarak değil yalıtımlı olarak test edin.
Denetleyici birim testlerini göstermek için örnek uygulamada aşağıdaki denetleyiciyi gözden geçirin.
Örnek kodu görüntüleme veya indirme (indirme)
Denetleyici Home , beyin fırtınası oturumlarının listesini görüntüler ve POST isteğiyle yeni beyin fırtınası oturumları oluşturulmasına olanak tanır:
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));
}
}
Önceki denetleyici:
- Açık Bağımlılıklar İlkesi'ni izler.
-
Bağımlılık eklemenin (DI) bir örneğini sağlamasını
IBrainstormSessionRepositorybekler. - Moq
IBrainstormSessionRepositorybir sahte nesne çerçevesi kullanılarak sahte bir hizmetle test edilebilir. Sahte nesne, test için kullanılan önceden belirlenmiş bir özellik ve yöntem davranışları kümesine sahip, oluşturulmuş bir nesnedir. Daha fazla bilgi için bkz . Tümleştirme testlerine giriş.
Yöntemin HTTP GET Index döngü veya dallanma yoktur ve yalnızca bir yöntemi çağırır. Bu eylem için birim testi:
-
IBrainstormSessionRepositoryyöntemini kullanarak hizmetle dalga geçerGetTestSessions.GetTestSessionstarihler ve oturum adları içeren iki sahte beyin fırtınası oturumu oluşturur. - yöntemini yürütür
Index. - yöntemi tarafından döndürülen sonuç üzerinde onaylar yapar:
- döndürülür ViewResult .
-
ViewDataDictionary.Model bir
StormSessionViewModel'dir. - içinde
ViewDataDictionary.Modeldepolanan iki beyin fırtınası oturumu vardır.
[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;
}
Denetleyicinin HomeHTTP POST Index yöntem testleri aşağıdakileri doğrular:
-
ModelState.IsValid olduğunda
false, eylem yöntemi uygun verilerle 400 Hatalı İstek ViewResult. - olduğunda
ModelState.IsValidtrue:-
AddDepodaki yöntemi çağrılır. - doğru RedirectToActionResult bağımsız değişkenlerle döndürülür.
-
Geçersiz bir model durumu, aşağıdaki ilk testte gösterildiği gibi kullanılarak AddModelError hata eklenerek test edilir:
[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();
}
ModelState geçerli olmadığında, get isteğiyle aynı ViewResult değer döndürülür. Test geçersiz bir model geçirmeyi denemez. Model bağlaması çalışmadığından (tümleştirme testi model bağlamayı kullansa da) geçersiz bir model geçirmek geçerli bir yaklaşım değildir. Bu durumda model bağlaması test edilmedi. Bu birim testleri yalnızca eylem yöntemindeki kodu test eder.
İkinci test, geçerli olduğunda ModelState bunu doğrular:
- Yeni
BrainstormSessionbir eklenmiştir (depo aracılığıyla). - yöntemi beklenen özelliklere sahip bir
RedirectToActionResultdöndürür.
Çağrılmayan sahte çağrılar normalde yoksayılır, ancak Verifiable kurulum çağrısının sonunda çağrılması testte sahte doğrulamaya olanak tanır. Bu, beklenen yöntem çağrılmadıysa testi başarısız olan çağrısıyla mockRepo.Verifygerçekleştirilir.
Note
Bu örnekte kullanılan Moq kitaplığı, doğrulanabilir veya "katı" olan sahteleri doğrulanamayan sahtelerle ("gevşek" sahteler veya saplamalar olarak da adlandırılır) karıştırmayı mümkün kılar. Moq ile Sahte davranışı özelleştirme hakkında daha fazla bilgi edinin.
Örnek uygulamadaki SessionController , belirli bir beyin fırtınası oturumuyla ilgili bilgileri görüntüler. Denetleyici geçersiz id değerlerle ilgilenmek için mantık içerir (aşağıdaki örnekte bu senaryoları kapsayan iki return senaryo vardır). Son return deyim görünüme yeni StormSessionViewModel bir değer döndürür (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);
}
}
Birim testleri, Oturum denetleyicisi return eylemindeki her Index senaryo için bir test içerir:
[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);
}
Fikirler denetleyicisine taşınan uygulama, yönlendirmede api/ideas web API'si olarak işlevselliği kullanıma sunar:
- Bir beyin fırtınası oturumuyla ilişkili fikirlerin (
IdeaDTO) listesi yöntemi tarafındanForSessiondöndürülür. -
Createyöntemi bir oturuma yeni fikirler ekler.
[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);
}
İş etki alanı varlıklarını doğrudan API çağrıları aracılığıyla döndürmekten kaçının. Etki alanı varlıkları:
- Genellikle istemcinin gerektirdiğinden daha fazla veri ekleyin.
- Uygulamanın iç etki alanı modelini gereksiz yere genel kullanıma sunulan API ile ilişkilendirin.
Etki alanı varlıkları ile istemciye döndürülen türler arasında eşleme gerçekleştirilebilir:
- Örnek uygulama tarafından kullanılan linq
Selectile el ile. Daha fazla bilgi için bkz . LINQ (Dil Tümleşik Sorgusu). - AutoMapper gibi bir kitaplıkla otomatik olarak.
Ardından örnek uygulama, Ideas denetleyicisinin Create ve ForSession API yöntemleri için birim testlerini gösterir.
Örnek uygulama iki ForSession test içerir. İlk test, geçersiz bir ForSession oturum için bir (HTTP Bulunamadı) döndürip döndürmediğini NotFoundObjectResult belirler:
[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);
}
İkinci ForSession test, geçerli bir oturum için oturum fikirlerinin () listesinin döndürülpForSession döndürülmediğini <List<IdeaDTO>> belirler. Denetimler, özelliğinin doğru olduğunu onaylamak Name için ilk fikri de inceler:
[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);
}
geçersiz olduğunda Create yönteminin ModelState davranışını test etmek için örnek uygulama, test kapsamında denetleyiciye bir model hatası ekler. Birim testlerinde model doğrulamayı veya model bağlamayı test etmeye çalışmayın; yalnızca geçersiz ModelStatebir ile karşılaştığınızda eylem yönteminin davranışını test edin:
[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);
}
İkinci testi Create , döndüren nulldepoya bağlıdır, bu nedenle sahte depo döndürecek nullşekilde yapılandırılır. Bir test veritabanı (bellekte veya başka bir şekilde) oluşturmanıza ve bu sonucu döndüren bir sorgu oluşturmanıza gerek yoktur. Test, örnek kodda gösterildiği gibi tek bir deyimde gerçekleştirilebilir:
[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);
}
Üçüncü Create test olan Create_ReturnsNewlyCreatedIdeaForSession, deponun UpdateAsync yönteminin çağrıldığını doğrular. Sahte ile çağrılır Verifiableve doğrulanabilir yöntemin yürütülür olduğunu onaylamak için sahte deponun Verify yöntemi çağrılır. Yöntemin verileri kaydettiğinden emin olmak UpdateAsync birim testinin sorumluluğu değildir. Bu işlem tümleştirme testiyle gerçekleştirilebilir.
[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);
}
Test EylemSonucu<T>
ActionResult<T> (ActionResult<TValue>), belirli bir türden türetilen ActionResult bir tür döndürebilir veya döndürebilir.
Örnek uygulama, belirli bir oturum List<IdeaDTO>için bir id döndüren bir yöntem içerir. Oturum id yoksa denetleyici döndürür NotFound:
[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;
}
denetleyicinin ForSessionActionResult iki testi içinde ApiIdeasControllerTestsyer alır.
İlk test, denetleyicinin var olmayan bir ActionResult oturum idiçin var olmayan bir fikir listesi döndürdüğünü onaylar:
- Türü
ActionResultşeklindedirActionResult<List<IdeaDTO>>. - Result bir 'dirNotFoundObjectResult.
[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);
}
Geçerli bir oturum idiçin, ikinci test yöntemin döndürdüğünü onaylar:
-
ActionResultTürü olan birList<IdeaDTO>. -
ActionResult<T>. Değer bir
List<IdeaDTO>türdür. - Listedeki ilk öğe, sahte oturumda depolanan fikirle eşleşen geçerli bir fikirdir (çağrılarak
GetTestSessionelde edilir).
[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);
}
Örnek uygulama ayrıca belirli bir oturum için yeni Idea bir oluşturma yöntemi de içerir. Denetleyici şunu döndürür:
- BadRequest geçersiz bir model için.
- NotFound oturum yoksa.
- CreatedAtAction oturum yeni fikirle güncelleştirildiğinde.
[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);
}
üç testi CreateActionResult içinde ApiIdeasControllerTestsyer alır.
İlk metin, geçersiz bir model için döndürüldüğünü BadRequest onaylar.
[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);
}
İkinci test, oturum yoksa döndürüldüğünü NotFound denetler.
[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);
}
Geçerli bir oturum idiçin son test şunları onaylar:
- yöntemi türüne sahip bir
ActionResultBrainstormSessiondöndürür. -
ActionResult<T>. Sonuç bir CreatedAtActionResult'dir.
CreatedAtActionResult, üst bilgi içeren 201 Created. -
ActionResult<T>. Değer bir
BrainstormSessiontürdür. - oturumunu
UpdateAsync(testSession)güncelleştirmek için sahte çağrı çağrıldı. YöntemVerifiableçağrısı onaylarda yürütülerekmockRepo.Verify()denetlenir. - Oturum için iki
Ideanesne döndürülür. - Son öğe (
Ideasahte çağrıUpdateAsynctarafından öğesinin eklenmesi) testteki oturuma eklenen öğeyle eşleşirnewIdea.
[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);
}
Denetleyiciler herhangi bir ASP.NET Core MVC uygulamasında merkezi bir rol oynar. Bu nedenle, denetleyicilerin amaçlanan şekilde davrandığını bilmelisiniz. Otomatikleştirilmiş testler, uygulama bir üretim ortamına dağıtılmadan önce hataları algılayabilir.
Örnek kodu görüntüleme veya indirme (indirme)
Denetleyici mantığının birim testleri
Birim testleri , bir uygulamanın bir bölümünü altyapısından ve bağımlılıklarından yalıtılarak test etmeyi içerir. Birim testi denetleyicisi mantığı, bağımlılıklarının veya çerçevenin davranışını değil, yalnızca tek bir eylemin içeriğini test eder.
Denetleyicinin davranışına odaklanmak için denetleyici eylemlerinin birim testlerini ayarlayın. Denetleyici birim testi filtreler, yönlendirme ve model bağlama gibi senaryoları önler. Bir isteğe toplu olarak yanıt veren bileşenler arasındaki etkileşimleri kapsayan testler tümleştirme testleri tarafından işlenir. Tümleştirme testleri hakkında daha fazla bilgi için bkz . ASP.NET Core'da tümleştirme testleri.
Özel filtreler ve yollar yazıyorsanız, birim testi bunları belirli bir denetleyici eylemindeki testlerin parçası olarak değil yalıtımlı olarak test edin.
Denetleyici birim testlerini göstermek için örnek uygulamada aşağıdaki denetleyiciyi gözden geçirin. Denetleyici Home , beyin fırtınası oturumlarının listesini görüntüler ve POST isteğiyle yeni beyin fırtınası oturumları oluşturulmasına olanak tanır:
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));
}
}
Önceki denetleyici:
- Açık Bağımlılıklar İlkesi'ni izler.
-
Bağımlılık eklemenin (DI) bir örneğini sağlamasını
IBrainstormSessionRepositorybekler. - Moq
IBrainstormSessionRepositorybir sahte nesne çerçevesi kullanılarak sahte bir hizmetle test edilebilir. Sahte nesne, test için kullanılan önceden belirlenmiş bir özellik ve yöntem davranışları kümesine sahip, oluşturulmuş bir nesnedir. Daha fazla bilgi için bkz . Tümleştirme testlerine giriş.
Yöntemin HTTP GET Index döngü veya dallanma yoktur ve yalnızca bir yöntemi çağırır. Bu eylem için birim testi:
-
IBrainstormSessionRepositoryyöntemini kullanarak hizmetle dalga geçerGetTestSessions.GetTestSessionstarihler ve oturum adları içeren iki sahte beyin fırtınası oturumu oluşturur. - yöntemini yürütür
Index. - yöntemi tarafından döndürülen sonuç üzerinde onaylar yapar:
- döndürülür ViewResult .
-
ViewDataDictionary.Model bir
StormSessionViewModel'dir. - içinde
ViewDataDictionary.Modeldepolanan iki beyin fırtınası oturumu vardır.
[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;
}
Denetleyicinin HomeHTTP POST Index yöntem testleri aşağıdakileri doğrular:
-
ModelState.IsValid olduğunda
false, eylem yöntemi uygun verilerle 400 Hatalı İstek ViewResult. - olduğunda
ModelState.IsValidtrue:-
AddDepodaki yöntemi çağrılır. - doğru RedirectToActionResult bağımsız değişkenlerle döndürülür.
-
Geçersiz bir model durumu, aşağıdaki ilk testte gösterildiği gibi kullanılarak AddModelError hata eklenerek test edilir:
[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();
}
ModelState geçerli olmadığında, get isteğiyle aynı ViewResult değer döndürülür. Test geçersiz bir model geçirmeyi denemez. Model bağlaması çalışmadığından (tümleştirme testi model bağlamayı kullansa da) geçersiz bir model geçirmek geçerli bir yaklaşım değildir. Bu durumda model bağlaması test edilmedi. Bu birim testleri yalnızca eylem yöntemindeki kodu test eder.
İkinci test, geçerli olduğunda ModelState bunu doğrular:
- Yeni
BrainstormSessionbir eklenmiştir (depo aracılığıyla). - yöntemi beklenen özelliklere sahip bir
RedirectToActionResultdöndürür.
Çağrılmayan sahte çağrılar normalde yoksayılır, ancak Verifiable kurulum çağrısının sonunda çağrılması testte sahte doğrulamaya olanak tanır. Bu, beklenen yöntem çağrılmadıysa testi başarısız olan çağrısıyla mockRepo.Verifygerçekleştirilir.
Note
Bu örnekte kullanılan Moq kitaplığı, doğrulanabilir veya "katı" olan sahteleri doğrulanamayan sahtelerle ("gevşek" sahteler veya saplamalar olarak da adlandırılır) karıştırmayı mümkün kılar. Moq ile Sahte davranışı özelleştirme hakkında daha fazla bilgi edinin.
Örnek uygulamadaki SessionController , belirli bir beyin fırtınası oturumuyla ilgili bilgileri görüntüler. Denetleyici geçersiz id değerlerle ilgilenmek için mantık içerir (aşağıdaki örnekte bu senaryoları kapsayan iki return senaryo vardır). Son return deyim görünüme yeni StormSessionViewModel bir değer döndürür (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);
}
}
Birim testleri, Oturum denetleyicisi return eylemindeki her Index senaryo için bir test içerir:
[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);
}
Fikirler denetleyicisine taşınan uygulama, yönlendirmede api/ideas web API'si olarak işlevselliği kullanıma sunar:
- Bir beyin fırtınası oturumuyla ilişkili fikirlerin (
IdeaDTO) listesi yöntemi tarafındanForSessiondöndürülür. -
Createyöntemi bir oturuma yeni fikirler ekler.
[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);
}
İş etki alanı varlıklarını doğrudan API çağrıları aracılığıyla döndürmekten kaçının. Etki alanı varlıkları:
- Genellikle istemcinin gerektirdiğinden daha fazla veri ekleyin.
- Uygulamanın iç etki alanı modelini gereksiz yere genel kullanıma sunulan API ile ilişkilendirin.
Etki alanı varlıkları ile istemciye döndürülen türler arasında eşleme gerçekleştirilebilir:
- Örnek uygulama tarafından kullanılan linq
Selectile el ile. Daha fazla bilgi için bkz . LINQ (Dil Tümleşik Sorgusu). - AutoMapper gibi bir kitaplıkla otomatik olarak.
Ardından örnek uygulama, Ideas denetleyicisinin Create ve ForSession API yöntemleri için birim testlerini gösterir.
Örnek uygulama iki ForSession test içerir. İlk test, geçersiz bir ForSession oturum için bir (HTTP Bulunamadı) döndürip döndürmediğini NotFoundObjectResult belirler:
[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);
}
İkinci ForSession test, geçerli bir oturum için oturum fikirlerinin () listesinin döndürülpForSession döndürülmediğini <List<IdeaDTO>> belirler. Denetimler, özelliğinin doğru olduğunu onaylamak Name için ilk fikri de inceler:
[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);
}
geçersiz olduğunda Create yönteminin ModelState davranışını test etmek için örnek uygulama, test kapsamında denetleyiciye bir model hatası ekler. Birim testlerinde model doğrulamayı veya model bağlamayı test etmeye çalışmayın; yalnızca geçersiz ModelStatebir ile karşılaştığınızda eylem yönteminin davranışını test edin:
[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);
}
İkinci testi Create , döndüren nulldepoya bağlıdır, bu nedenle sahte depo döndürecek nullşekilde yapılandırılır. Bir test veritabanı (bellekte veya başka bir şekilde) oluşturmanıza ve bu sonucu döndüren bir sorgu oluşturmanıza gerek yoktur. Test, örnek kodda gösterildiği gibi tek bir deyimde gerçekleştirilebilir:
[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);
}
Üçüncü Create test olan Create_ReturnsNewlyCreatedIdeaForSession, deponun UpdateAsync yönteminin çağrıldığını doğrular. Sahte ile çağrılır Verifiableve doğrulanabilir yöntemin yürütülür olduğunu onaylamak için sahte deponun Verify yöntemi çağrılır. Yöntemin verileri kaydettiğinden emin olmak UpdateAsync birim testinin sorumluluğu değildir. Bu işlem tümleştirme testiyle gerçekleştirilebilir.
[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);
}
Test ActionResult<T>
ASP.NET Core 2.1 veya sonraki sürümlerinde ActionResult <T> (ActionResult<TValue>), belirli bir türden ActionResult türetilen bir tür döndürmenizi veya döndürmenizi sağlar.
Örnek uygulama, belirli bir oturum List<IdeaDTO>için bir id döndüren bir yöntem içerir. Oturum id yoksa denetleyici döndürür NotFound:
[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;
}
denetleyicinin ForSessionActionResult iki testi içinde ApiIdeasControllerTestsyer alır.
İlk test, denetleyicinin var olmayan bir ActionResult oturum idiçin var olmayan bir fikir listesi döndürdüğünü onaylar:
- Türü
ActionResultşeklindedirActionResult<List<IdeaDTO>>. - Result bir 'dirNotFoundObjectResult.
[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);
}
Geçerli bir oturum idiçin, ikinci test yöntemin döndürdüğünü onaylar:
-
ActionResultTürü olan birList<IdeaDTO>. -
ActionResult<T>. Değer bir
List<IdeaDTO>türdür. - Listedeki ilk öğe, sahte oturumda depolanan fikirle eşleşen geçerli bir fikirdir (çağrılarak
GetTestSessionelde edilir).
[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);
}
Örnek uygulama ayrıca belirli bir oturum için yeni Idea bir oluşturma yöntemi de içerir. Denetleyici şunu döndürür:
- BadRequest geçersiz bir model için.
- NotFound oturum yoksa.
- CreatedAtAction oturum yeni fikirle güncelleştirildiğinde.
[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);
}
üç testi CreateActionResult içinde ApiIdeasControllerTestsyer alır.
İlk metin, geçersiz bir model için döndürüldüğünü BadRequest onaylar.
[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);
}
İkinci test, oturum yoksa döndürüldüğünü NotFound denetler.
[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);
}
Geçerli bir oturum idiçin son test şunları onaylar:
- yöntemi türüne sahip bir
ActionResultBrainstormSessiondöndürür. -
ActionResult<T>. Sonuç bir CreatedAtActionResult'dir.
CreatedAtActionResult, üst bilgi içeren 201 Created. -
ActionResult<T>. Değer bir
BrainstormSessiontürdür. - oturumunu
UpdateAsync(testSession)güncelleştirmek için sahte çağrı çağrıldı. YöntemVerifiableçağrısı onaylarda yürütülerekmockRepo.Verify()denetlenir. - Oturum için iki
Ideanesne döndürülür. - Son öğe (
Ideasahte çağrıUpdateAsynctarafından öğesinin eklenmesi) testteki oturuma eklenen öğeyle eşleşirnewIdea.
[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);
}
Ek kaynaklar
- ASP.NET Core'da tümleştirme testleri
- Visual Studio ile birim testleri oluşturma ve çalıştırma
- MyTested.AspNetCore.Mvc - ASP.NET Core MVC için Fluent Test Kitaplığı: Güçlü türe sahip birim testi kitaplığı, MVC ve web API uygulamalarını test etme için akıcı bir arabirim sağlar. (Microsoft tarafından korunmaz veya desteklenmez.)
- JustMockLite: .NET geliştiricileri için sahte bir çerçeve. (Microsoft tarafından korunmaz veya desteklenmez.)
ASP.NET Core