ASP.NET Core'da birim testi denetleyicisi mantığı
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ı
IBrainstormSessionRepository
bekler. - Moq gibi bir sahte
IBrainstormSessionRepository
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:
IBrainstormSessionRepository
yöntemini kullanarak hizmetle dalga geçerGetTestSessions
.GetTestSessions
tarihler 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.Model
depolanan 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 Home HTTP POST Index
yöntem testleri aşağıdakileri doğrular:
- ModelState.IsValid olduğunda
false
, eylem yöntemi uygun verilerle 400 Hatalı İstek ViewResult döndürür. - olduğunda
ModelState.IsValid
true
:Add
Depodaki 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
BrainstormSession
bir eklenmiştir (depo aracılığıyla). - yöntemi beklenen özelliklere sahip bir
RedirectToActionResult
dö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.Verify
gerçekleştirilir.
Not
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 Index
eylemindeki 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);
}
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ındanForSession
döndürülür. Create
yö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
Select
ile 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 NotFoundObjectResult oturum için bir (HTTP Bulunamadı) döndürip döndürmediğini ForSession
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ülp<List<IdeaDTO>>
döndürülmediğini ForSession
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 ModelState
yönteminin Create
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 ModelState
bir 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 null
depoya 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 Verifiable
ve 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>
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 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 ApiIdeasControllerTests
yer alır.
İlk test, denetleyicinin var olmayan bir ActionResult
oturum id
iç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 id
için, ikinci test yöntemin döndürdüğünü onaylar:
ActionResult
Tü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
GetTestSession
elde 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 ApiIdeasControllerTests
yer 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 id
için son test şunları onaylar:
- yöntemi türüne sahip bir
ActionResult
BrainstormSession
döndürür. - ActionResult<T>. Sonuç bir CreatedAtActionResult'dir.
CreatedAtActionResult
, üst bilgi içeren 201 Created yanıtınaLocation
benzer. - ActionResult<T>. Değer bir
BrainstormSession
tü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
Idea
nesne döndürülür. - Son öğe (
Idea
sahte çağrıUpdateAsync
tarafı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ı
IBrainstormSessionRepository
bekler. - Moq gibi bir sahte
IBrainstormSessionRepository
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:
IBrainstormSessionRepository
yöntemini kullanarak hizmetle dalga geçerGetTestSessions
.GetTestSessions
tarihler 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.Model
depolanan 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 Home HTTP POST Index
yöntem testleri aşağıdakileri doğrular:
- ModelState.IsValid olduğunda
false
, eylem yöntemi uygun verilerle 400 Hatalı İstek ViewResult döndürür. - olduğunda
ModelState.IsValid
true
:Add
Depodaki 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
BrainstormSession
bir eklenmiştir (depo aracılığıyla). - yöntemi beklenen özelliklere sahip bir
RedirectToActionResult
dö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.Verify
gerçekleştirilir.
Not
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 Index
eylemindeki 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);
}
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ındanForSession
döndürülür. Create
yö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
Select
ile 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 NotFoundObjectResult oturum için bir (HTTP Bulunamadı) döndürip döndürmediğini ForSession
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ülp<List<IdeaDTO>>
döndürülmediğini ForSession
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 ModelState
yönteminin Create
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 ModelState
bir 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 null
depoya 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 Verifiable
ve 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 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 ApiIdeasControllerTests
yer alır.
İlk test, denetleyicinin var olmayan bir ActionResult
oturum id
iç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 id
için, ikinci test yöntemin döndürdüğünü onaylar:
ActionResult
Tü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
GetTestSession
elde 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 ApiIdeasControllerTests
yer 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 id
için son test şunları onaylar:
- yöntemi türüne sahip bir
ActionResult
BrainstormSession
döndürür. - ActionResult<T>. Sonuç bir CreatedAtActionResult'dir.
CreatedAtActionResult
, üst bilgi içeren 201 Created yanıtınaLocation
benzer. - ActionResult<T>. Değer bir
BrainstormSession
tü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
Idea
nesne döndürülür. - Son öğe (
Idea
sahte çağrıUpdateAsync
tarafı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