我应该嘲笑或伪造我的存储库吗?

本文关键字:存储 我的 伪造 该嘲笑 | 更新日期: 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而出名)在这里有一篇关于测试存储库的好博客。