【问题标题】:Unit Test MVC 5 Controller Create Action with Unit of Work and Repository单元测试 MVC 5 控制器使用工作单元和存储库创建操作
【发布时间】:2016-11-20 09:38:49
【问题描述】:

我正在尝试测试接受视图模型并创建新条目的控制器操作。这是控制器动作:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ContactViewModel viewModel)
{
    if (!ModelState.IsValid)
        return View("Create", viewModel);

    _unitOfWork.Contacts.Add(Mapper.Map(viewModel, new Contact()));  

    _unitOfWork.Complete();

    return RedirectToAction("Index");
}

还有单元测试:

[TestClass]
public class ContactControllerTests
{
    private ContactsController _controller;
    private Mock<IContactRepository> _mockRepository;
    private string _userId;
    private Mock<IUnitOfWork> _mockUoW;

    [ClassInitialize]
    public static void Init(TestContext context)
    {
        Mapper.Initialize(c => c.AddProfile<MappingProfile>());
    }

    [TestInitialize]
    public void TestInitialize()
    {
        _userId = "1";
        _mockRepository = new Mock<IContactRepository>();
        _mockUoW = new Mock<IUnitOfWork>();

        _mockUoW.SetupGet(u => u.Contacts).Returns(_mockRepository.Object);

        _controller = new ContactsController(_mockUoW.Object);

        _controller.MockCurrentUser(_userId, "user@domain.com");
    }

    [TestMethod]
    public void CreatePost_ValidValuesSubmitted_ShouldCallComplete()
    {
        var viewModel = new ContactViewModel()
        {
            FirstName = "a",
            LastName = "b"
        };

        _controller.Create(viewModel);

        _mockRepository.Object.GetContacts(_userId).Should().HaveCount(1);
    }
}

单元测试总是返回计数 0,而我期望它是 1。我对 TDD 很陌生,我实现了工作单元和存储库模式,如 Mosh Hamedani 的课程所示: https://app.pluralsight.com/library/courses/full-stack-dot-net-developer-architecture-testing/table-of-contents

【问题讨论】:

  • 如果你想测试一段已经写好的代码,这不是 TDD(测试 Driven)...

标签: c# asp.net-mvc unit-testing moq


【解决方案1】:

在上面的示例中,您没有模拟存储库的任何行为。

根据提供的示例,让我们假设这样一个简单的界面。

public interface IContactRepository {
    void Add(Contact contact);
    IEnumerable<Contact> GetContacts(string _userId);
}

您需要有某种形式的数据存储。

[TestInitialize]
public void TestInitialize() {
    _userId = "1";
    var data = new List<Contact>();//To store test data.
    //Configure repository
    _mockRepository = new Mock<IContactRepository>();
    _mockRepository.Setup(m => m.Add(It.IsAny<Contact>())).Callback<Contact>(data.Add);
    _mockRepository.Setup(m => m.GetContacts(_userId)).Returns(data);
    //Configure UoW
    _mockUoW = new Mock<IUnitOfWork>();
    _mockUoW.SetupGet(u => u.Contacts).Returns(_mockRepository.Object);

    _controller = new ContactsController(_mockUoW.Object);

    _controller.MockCurrentUser(_userId, "user@domain.com");
}

或放弃模拟并创建一个假的。

public class FakeContactRepository : IContactRepository {
    private ICollection<Contact> data;

    public FakeContactRepository(ICollection<Contact> data) {                
        this.data = data;
    }

    public void Add(Contact contact) {
        data.Add(contact);
    }

    public IEnumerable<Contact> GetContacts(string _userId) {
        return data;
    }
}

并为测试设置它。

[TestInitialize]
public void TestInitialize() {
    _userId = "1";
    var data = new List<Contact>();//To store test data.
    //Configure repository
    var fakeRepository = new FakeContactRepository(data);
    //Configure UoW
    _mockUoW = new Mock<IUnitOfWork>();
    _mockUoW.SetupGet(u => u.Contacts).Returns(fakeRepository );

    _controller = new ContactsController(_mockUoW.Object);

    _controller.MockCurrentUser(_userId, "user@domain.com");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多