我应该嘲笑或伪造我的存储库吗?
本文关键字:存储 我的 伪造 该嘲笑 | 更新日期: 2023-09-27 18:15:14
我有一个名为PostsController
的控制器
public class PostsController : Controller
{
private const int PageSize = 8;
private readonly IPostsRepository repository;
public PostsController(IPostsRepository repository)
{
this.repository = repository;
}
public ViewResult Index(int pageNumber = 1)
{
var posts =
repository.All()
.Where(post => !post.Draft)
.OrderBy(post => post.PublishedAt);
var model =
posts.MapTo<PostViewModel>()
.ToPagedList(pageNumber, PageSize);
return View("Index", model);
}
public ActionResult Post(string slug)
{
var post =
repository.Find(slug);
if (post == null || post.Draft)
{
return HttpNotFound();
}
return View("Post", post.MapTo<PostViewModel>());
}
}
和相应的测试夹具PostsControllerTest
[TestFixture]
public class PostsControllerTest
{
private PostsController controller;
private Mock<IPostsRepository> repository;
[SetUp]
public void SetUp()
{
AutoMapperConfig.Configure();
repository = new Mock<IPostsRepository>();
controller = new PostsController(repository.Object);
}
[Test]
public void Index_ReturnsCorrectViewName()
{
var actual = controller.Index();
Assert.AreEqual(actual.ViewName, "Index");
}
[Test]
public void Index_ReturnsCorrectModel()
{
var result = controller.Index();
var actual = result.Model as PagedList<PostViewModel>;
Assert.NotNull(actual);
}
[Test]
public void Index_WithPageNumber_ReturnsCorrectViewName()
{
var actual = controller.Index(2);
Assert.AreEqual(actual.ViewName, "Index");
}
[Test]
public void Index_WithPageNumber_ReturnsCorrectModel()
{
var result = controller.Index(2);
var actual = result.Model as PagedList<PostViewModel>;
Assert.NotNull(actual);
}
[Test]
public void Post_ReturnsCorrectViewName()
{
repository.Setup(repo => repo.Find("abc"))
.Returns(new Post());
var actual = controller.Post("abc") as ViewResult;
Assert.NotNull(actual);
Assert.AreEqual(actual.ViewName, "Post");
}
[Test]
public void Post_ThatIsDraft_ReturnsNotFound()
{
var post = new Post { Draft = true };
repository.Setup(repo => repo.Find("abc"))
.Returns(post);
var actual = controller.Post("abc");
Assert.IsAssignableFrom<HttpNotFoundResult>(actual);
}
[Test]
public void Post_ThatDoesNotExist_ReturnNotFound()
{
var actual = controller.Post("abc");
Assert.IsAssignableFrom<HttpNotFoundResult>(actual);
}
[Test]
public void Post_ReturnsCorrectModel()
{
var post = new Post
{
Slug = "continuing-to-an-outer-loop",
Title = "Continuing to an outer loop",
Summary = "When you have a nested loop, sometimes",
Content = "When you have a nested loop, sometimes",
PublishedAt = DateTime.Now.AddDays(7),
Tags = new Collection<Tag> { new Tag { Name = "Programming" } }
};
repository.Setup(repo => repo.Find("continuing-to-an-outer-loop"))
.Returns(post);
var viewResult = (ViewResult)controller.Post("continuing-to-an-outer-loop");
var actual = viewResult.Model as PostViewModel;
Assert.NotNull(actual);
Assert.AreEqual(actual.Slug, post.Slug);
Assert.AreEqual(actual.Title, post.Title);
Assert.AreEqual(actual.Summary, post.Summary);
Assert.AreEqual(actual.Content, post.Content);
Assert.AreEqual(actual.PublishedAt, post.PublishedAt);
Assert.AreEqual(actual.Tags, post.Tags);
}
}
通过观察其他项目如何安排测试,我学会了用这种方式模拟存储库。可以在这里找到这种方法的一个特定示例(我从中学习)。就我个人而言,我发现这种方法有些费力。此外,自从采用这种方法以来,我偶然发现了一篇文章,上面说你不应该模仿你的存储库,而应该假装它。
现在我很矛盾。我应该继续模拟我的存储库还是替换它?
我恳请您包括代码示例,显示如何伪造和种子在这种情况下的存储库,因为我不确定如何这样做。
要选边站,我得说嘲弄是可以的,而且比假装更省事。
但是要表达我的观点——又不想显得尴尬——我会说……既不。
考虑通过Index操作而没有碰到真正的存储库的测试增加了多少价值-你正在测试的绝大多数代码是在Linq和AutoMapper中,这两个代码都已经被其他人进行了大量测试。
我建议编写集成测试,通过控制器操作,通过实际存储库,撞击数据库并从另一边返回。这增加了价值,并为您提供了一些真正的保证,即您的系统()你已经写的比特实际上是有效的。
最后,Jimmy Bogard(因AutoMapper而出名)在这里有一篇关于测试存储库的好博客。