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 altyapısından ve bağımlılıklarından yalıtılmış bir bölümünü test etmeyi içerir. Denetleyici mantığı birim testi yapılırken, bağımlılıklarının veya çerçevenin davranışı değil, yalnızca tek bir eylemin içeriği test edilir.
Denetleyicilerin birim testi
Denetleyicinin davranışına odaklanmak için denetleyici eylemleri için birim testleri oluşturun. Denetleyici birim testi filtreler, yönlendirme ve model bağlama gibi senaryolardan kaçınır. Bir isteğe toplu olarak yanıt veren bileşenler arasındaki etkileşimleri kapsayan testler, tümleştirme testleri tarafından ele alınır. 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 (nasıl indirilir)
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 enjeksiyonunun (DI),
IBrainstormSessionRepositoryörneğini sağlaması beklenir. - Moq gibi bir sahte nesne çerçevesi kullanılarak sahte
IBrainstormSessionRepositoryhizmetle test edilebilir. Sahte nesne, test amacıyla kullanılan, özellikleri ve yöntemleri için önceden tanımlanmış davranışlara sahip yapay olarak oluşturulmuş bir nesnedir. Daha fazla bilgi için Tümleştirme testlerine giriş konusuna bakın.
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:
-
IBrainstormSessionRepositoryhizmetiniGetTestSessionsyöntemini kullanarak taklit eder.GetTestSessionstarihler ve oturum adları içeren iki sahte beyin fırtınası oturumu oluşturur. -
Indexyöntemini yürütür. - Yöntemin döndürdüğü sonuç üzerinde doğrulamalar yapar:
- Bir ViewResult döndürülür.
-
ViewDataDictionary.Model bir
StormSessionViewModel'dir. -
ViewDataDictionary.Modeliçinde depolanan iki beyin fırtınası oturumu bulunuyor.
[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 şunları doğrular:
-
ModelState.IsValid olduğunda
false, eylem yöntemi uygun verilerle 400 Hatalı İstek ViewResult. - olduğunda
ModelState.IsValidtrue:-
Adddepo nesnesindeki yöntem ç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 AddModelError kullanılarak 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 döndürülür. Test geçersiz bir model geçirmeyi denemez. Model bağlama çalışmadığından, geçersiz bir model iletmek geçerli bir yaklaşım değildir (her ne kadar bir entegrasyon testi model bağlamayı kullansa da). Bu durumda model bağlama test edilmemiştir. Bu birim testleri yalnızca eylem yöntemindeki kodu test eder.
İkinci test, geçerli olduğunda ModelState bunu doğrular:
- Depo aracılığıyla yeni bir
BrainstormSessioneklenmiştir. - 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 mock doğrulamasına olanak tanır. Bu, mockRepo.Verify çağrısı ile gerçekleştirilir; beklenen yöntem çağrılmadıysa bu çağrı testi başarısız kılar.
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ğerlerini ele almak için mantık içerir (aşağıdaki örnekte bu durumları kapsamak için iki return senaryosu vardır). Son return ifade, görünüme yeni bir StormSessionViewModel 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, Session denetleyicisindeki Index action'ında yer alan her return 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);
}
Ideas denetleyicisine geçildiğinde uygulama, api/ideas rotasında bir 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. Alan varlıkları:
- Genellikle istemcinin gerektirdiğinden daha fazla veri içerir.
- Uygulamanın iç etki alanı modelini gereksiz yere genel kullanıma sunulan API ile ilişkilendirin.
Etki alanı varlıkları ile istemciye dönen 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 testi içerir. İlk test, ForSession öğesinin geçersiz bir oturum için NotFoundObjectResult (HTTP Not Found) döndürüp döndürmediğini 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 testi, ForSession öğesinin geçerli bir oturum için bir oturum fikirleri listesi (<List<IdeaDTO>>) döndürüp döndürmediğini 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);
}
ModelState geçersiz olduğunda Create yönteminin davranışını test etmek için örnek uygulama, testin bir parçası olarak denetleyiciye bir model hatası ekler. Birim testlerinde model doğrulamayı veya model bağlamayı test etmeye çalışmayın; yalnızca geçersiz bir ModelState 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 test, deponun null döndürmesine bağlıdır, bu nedenle sahte depo null döndürecek şekilde yapılandırılmıştır; Create. 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. Örnek kodun gösterdiği gibi, bu test tek bir ifadeyle yapılabilir:
[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. Mock, Verifiable ile çağrılır ve doğrulanabilir yöntemin yürütüldüğünü onaylamak için sahte deponun Verify yöntemi çağrılır.
UpdateAsync yönteminin verileri kaydettiğinden emin olmak 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>), ActionResult türünden türeyen bir tür veya belirli bir tür döndürebilir.
Örnek uygulama, belirli bir oturum id için bir List<IdeaDTO> 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 ActionResult döndürdüğünü, ancak var olmayan bir ActionResult oturumu için var olmayan bir fikir listesi döndürmediğini onaylar:
- Türü
ActionResultşeklindedirActionResult<List<IdeaDTO>>. - Result, bir NotFoundObjectResultdir.
[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:
-
List<IdeaDTO>türüne sahip birActionResult. -
ActionResult<T>.Value bir
List<IdeaDTO>türdür. - Listedeki ilk öğe,
GetTestSessionçağrısı yapılarak elde edilen ve mock oturumunda depolanan fikirle eşleşen geçerli bir fikirdir.
[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 verilen bir oturum için yeni bir Idea oluşturma yöntemi de içerir. Denetleyici şunu döndürür:
- BadRequest geçersiz model için.
- NotFound oturum mevcut değilse.
- 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);
}
ApiIdeasControllerTests içinde CreateActionResult için üç test yer alır.
İlk metin, geçersiz bir model için BadRequest döndürüldüğünü 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 NotFound döndürüldüğünü 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öntem,
BrainstormSessiontüründe birActionResultdöndürür. -
ActionResult<T>.Result bir CreatedAtActionResult.
CreatedAtActionResult, üst bilgisi içeren bir 201 Created yanıtına benzerdir. -
ActionResult<T>. Değer bir
BrainstormSessiontürdür. - Oturumu güncelleştirmek için yapılan sahte çağrı,
UpdateAsync(testSession), çağrıldı.Verifiableyöntem çağrısı, doğrulamalardamockRepo.Verify()çalıştırılarak denetlenir. - Oturum için iki
Ideanesne döndürülür. - Son öğe (
UpdateAsynciçin yapılan sahte çağrının eklediğiIdea), testte oturuma eklenennewIdeaöğesiyle eşleşir.
[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çlandığı şekilde davrandığından emin olabilirsiniz. Otomatikleştirilmiş testler, uygulama bir üretim ortamına dağıtılmadan önce hataları algılayabilir.
Örnek kodu görüntüleme veya indirme (nasıl indirilir)
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ıtarak test etmeyi içerir. Denetleyici mantığına birim testi uygulandığında, bağımlılıklarının veya çerçevenin davranışı değil, yalnızca tek bir eylemin içeriği test edilir.
Denetleyicinin davranışına odaklanmak için denetleyici eylemlerinin birim testlerini ayarlayın. Denetleyici birim testi filtreler, yönlendirme ve model bağlama gibi senaryolardan kaçınır. Bir isteğe toplu olarak yanıt veren bileşenler arasındaki etkileşimleri kapsayan testler tümleştirme testleri ile ele alınır. Tümleştirme testleri hakkında daha fazla bilgi için bkz. ASP.NET Core'da tümleştirme testleri.
Özel filtreler ve yönlendirmeler yazıyorsanız, bunları belirli bir denetleyici eylemine yönelik testlerin parçası olarak değil, izole şekilde birim testiyle test edin.
Denetleyici birim testlerini göstermek için örnek uygulamada yer alan 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 takip eder.
-
bağımlılık enjeksiyonunun (DI),
IBrainstormSessionRepositoryörneğini sağlaması beklenir. - Moq
IBrainstormSessionRepositorybir sahte nesne çerçevesi kullanılarak sahte bir hizmetle test edilebilir. Mock 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 Tümleştirme testlerine giriş bölümüne bakın.
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:
-
IBrainstormSessionRepositoryhizmetiniGetTestSessionsyöntemini kullanarak taklit eder.GetTestSessionstarih ve oturum adlarıyla iki sahte beyin fırtınası oturumu oluşturur. -
Indexmetodunu yürütür. - yöntem tarafından döndürülen sonuç üzerinde doğrulamalar yapar:
- ViewResult döndürülür.
-
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öntemi şunu doğrular:
-
ModelState.IsValid olduğunda
false, eylem yöntemi uygun verilerle 400 Hatalı İstek ViewResult. -
ModelState.IsValid,trueolduğunda:- Repository üzerindeki
Addyöntemi çağrılır. - doğru RedirectToActionResult bağımsız değişkenlerle döndürülür.
- Repository üzerindeki
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 (her ne kadar bir 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ğlama test edilmez. Bu birim testleri yalnızca eylem yöntemindeki kodu test ederler.
İkinci test, ModelState geçerli olduğunda bunu doğrular:
- Yeni
BrainstormSessionbir eklenmiştir (depo aracılığıyla). - Yöntem, 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 mock doğrulamasına olanak tanır. Bu, mockRepo.Verify çağrısı ile gerçekleştirilir; beklenen yöntem çağrılmadıysa testi başarısız kılar.
Note
Bu örnekte kullanılan Moq kitaplığı, doğrulanabilir veya "katı" olan mock nesnelerini doğrulanamayan mock nesneleriyle ("gevşek" mock nesneleri veya stub'lar olarak da adlandırılır) karıştırmayı mümkün kılar. Moq ile Mock davranışını ö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ğerleri ele almak için mantık içerir (aşağıdaki örnekte bu senaryoları kapsamak için iki return senaryo vardır). Son return ifade, görünüme yeni bir StormSessionViewModel 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 denetleyicisindeki her return senaryo için Index eyleminde 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);
}
Ideas denetleyicisine geçildiğinde uygulama, api/ideas yolunda bir web API'si olarak işlevsellik sunar:
- Bir beyin fırtınası oturumuyla ilişkili fikirlerin (
IdeaDTO) listesiForSessionyöntemi tarafından dö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 içerirler.
- Uygulamanın iç etki alanı modelini gereksiz yere dışa açık API'ye bağlayın.
Etki alanı varlıkları ile istemciye döndürülen türler arasında eşleme gerçekleştirilebilir:
- Örnek uygulamanın kullandığı gibi, bir LINQ
Selectile manuel olarak. 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, ForSession geçersiz bir oturum için NotFoundObjectResult (HTTP Not Found) döndürüp döndürmediğini 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, ilk fikri de Name özelliğinin doğru olduğunu doğrulamak için 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 bir ModelStatemodelle 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);
}
Create öğesinin ikinci testi, deponun null döndürmesine bağlıdır, bu nedenle sahte depo, null döndürecek ş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. Mock, Verifiable ile çağrılır ve doğrulanabilir yöntemin yürütüldüğünü onaylamak için sahte deponun Verify yöntemi çağrılır.
UpdateAsync yönteminin verileri kaydettiğinden emin olmak 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>
ASP.NET Core 2.1 veya sonraki sürümlerde, ActionResult<T> (ActionResult<TValue>), ActionResult türünden türetilen bir tür veya belirli bir tür döndürmenizi sağlar.
Örnek uygulama, belirli bir oturum idiçin bir List<IdeaDTO> 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;
}
ForSessionActionResult denetleyicisinin iki testi ApiIdeasControllerTests içinde yer alır.
İlk test, denetleyicinin bir ActionResult döndürdüğünü, ancak var olmayan bir id için var olmayan bir fikir listesi döndürmediğini doğrular:
-
ActionResulttürüActionResult<List<IdeaDTO>>. - Result, bir NotFoundObjectResultdır.
[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 için id, ikinci test yöntemin şunu döndürdüğünü doğrular:
-
List<IdeaDTO>türüne sahip birActionResult. -
ActionResult<T>.Value bir
List<IdeaDTO>türdür. - Listedeki ilk öğe, sahte oturumda depolanan fikirle eşleşen geçerli bir fikirdir (
GetTestSessionçağrısıyla elde edilen).
[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 bir Idea oluşturma yöntemi de içerir. Denetleyici şunu döndürür:
- BadRequest geçersiz bir model.
- NotFound oturum mevcut değilse.
- 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);
}
ApiIdeasControllerTests içinde CreateActionResult ile ilgili üç test yer alır.
İlk metin, geçersiz bir model için BadRequest döndürüldüğünü 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 mevcut değilse NotFound döndürüldüğünü 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>.Result bir CreatedAtActionResult.
CreatedAtActionResult, üst bilgi içeren 201 Created. -
ActionResult<T>.Value bir
BrainstormSessiontürdür. - Oturumu güncelleyen sahte çağrı,
UpdateAsync(testSession), çağrıldı.Verifiableyöntem çağrısı, onaylardamockRepo.Verify()çalıştırılarak 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);
}
İlgili içerik
- 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 bir mocklama çerçevesi. (Microsoft tarafından bakımı yapılmaz veya desteklenmez.)
ASP.NET Core