我有一个名为 PostsController
的 Controller
public class PostsController : Controller
{
private readonly IPostsRepository repository;
public PostsController(IPostsRepository repository)
{
this.repository = repository;
}
public ViewResult Index()
{
var posts =
repository.All()
.OrderBy(post => post.PublishedAt);
return View("Index", posts.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_ReturnsCorrectModel()
{
var actual = controller.Index().Model;
Assert.IsAssignableFrom<IEnumerable<PostViewModel>>(actual);
}
}
目前我只测试 Controller 是否返回正确的模型类型。我是否还应该 stub 存储库并测试是否返回了正确的数据,如下所示:
[Test]
public void Index_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.All()).Returns(new[] { post });
var actual = controller.Index().Model as IEnumerable<PostViewModel>;
Assert.NotNull(actual);
Assert.AreEqual(1, actual.Count());
Assert.AreEqual(post.Title, actual.First().Title);
}
我感到非常沮丧,因为我不知道自己是否进行了正确的单元测试。清楚地解释我应该采取哪种方法,为什么会非常有帮助。
最佳答案
我认为您不需要测试 IPostRepository
的功能在这个单元测试中。您应该为它创建一个单独的单元测试类。
与 MapTo<T>
的功能类似应该单独测试。
单元测试应该只测试 SUT(被测系统)的功能,在本例中是 Index
你的方法PostsController
类。
这是一个简单的方法,因此您要在此单元测试中验证的两件事是:
1- repository.All()
方法被调用一次
2- 您的 View 模型已正确映射(您已经在做)
这就是我对该方法进行单元测试的方式:
[Test]
public void Index_ReturnsCorrectModel()
{
// Arrange
repository.Setup(repo => repo.All()).Returns(Enumerable.Empty<Post>());
// Act
var actual = controller.Index().Model;
// Assert
Assert.IsAssignableFrom<IEnumerable<PostViewModel>>(actual);
repository.Verify(repo => repo.All(), Times.Once);
}
此外,为了尽量减少安排单元测试所需的工作量,可以使用像 AutoFixture 这样的库,它会自动为您创建 post 对象。
关于c# - 我应该如何对返回模型的 Controller 进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25105161/