你如何使用Moq来模拟一个简单的界面?

时间:2011-04-11 20:47:22

标签: c# unit-testing dependency-injection mocking moq

好的,我有一个这样的业务逻辑类:

注意:对于上下文,供应商简报是描述PDF文档“下载”的简单实体。

/// <summary>
/// Houses business level functions for dealing with vendor briefs.
/// </summary>
public class VendorBriefController : IVendorBriefController
{
    /// <summary>
    /// Vendor brief controller requires an instance of IVendorBriefRepository.
    /// </summary>
    IVendorBriefRepository _vendorBriefRepository;

    /// <summary>
    /// Initializes an instance of VendorBriefController.
    /// </summary>
    public VendorBriefController(IVendorBriefRepository vendorBriefRepository)
    {
        _vendorBriefRepository = vendorBriefRepository;
    }

    /// <summary>
    /// Get a list of string filters for vendor briefs.
    /// </summary>
    /// <returns>A list of string filters.</returns>
    public dynamic GetFilters()
    {
        List<string> filters = new List<string>
        {
            "All",
            "Active",
            "Inactive"
        };
        return filters;
    }

    /// <summary>
    /// Retrieve vendor brief entity from the repository by its unique ID.
    /// </summary>
    /// <param name="Id">The unique ID of the vendor brief.</param>
    /// <returns>A vendor brief entity.</returns>
    public VendorBrief GetVendorBriefForEditing(int Id)
    {
        var vendorBrief = _vendorBriefRepository.GetVendorBrief(Id);
        return vendorBrief;
    }

    /// <summary>
    /// Get a dynamic list of vendor briefs from the repository based on the supplied filter.
    /// </summary>
    /// <param name="filter">The filter to be used when retrieving vendor briefs.</param>
    /// <returns>A dynamic sorted & filtered list of vendor briefs to be displayed in a grid view.</returns>
    public dynamic GetVendorBriefList(string filter)
    {
        IEnumerable<VendorBrief> results = _vendorBriefRepository.GetVendorBriefs();
        switch (filter)
        {
            default:
                results = _vendorBriefRepository.GetVendorBriefs();
                break;
            case "Active":
                results = _vendorBriefRepository.GetVendorBriefs(true);
                break;
            case "Inactive":
                results = _vendorBriefRepository.GetVendorBriefs(false);
                break;
        }
        return from x in results
               orderby x.DisplayOrder
               select new
               {
                   ID = x.VendorBriefID,
                   Title = x.Title,
                   Active = x.IsActive,
                   DisplayOrder = x.DisplayOrder
               };
    }

    /// <summary>
    /// Save changes to the underlying repository in order to persist changes made to self-tracking vendor brief entities.
    /// </summary>
    /// <param name="vendorBrief"></param>
    public void EditVendorBrief(VendorBrief vendorBrief)
    {
        _vendorBriefRepository.SaveChanges();
    }

    /// <summary>
    /// Remove a vendor brief from the underlying repository.
    /// </summary>
    /// <param name="vendorBrief">The vendor brief to be removed.</param>
    public void DeleteVendorBrief(VendorBrief vendorBrief)
    {
        _vendorBriefRepository.DeleteVendorBrief(vendorBrief);
        _vendorBriefRepository.SaveChanges();
    }

    /// <summary>
    /// Add a vendor brief to the underlying repository.
    /// </summary>
    /// <param name="vendorBrief">The vendor brief to be added.</param>
    public void AddVendorBrief(VendorBrief vendorBrief)
    {
        _vendorBriefRepository.AddVendorBrief(vendorBrief);
        _vendorBriefRepository.SaveChanges();
    }
}

我正在迈出单元测试的第一步,我正在学习Moq。我不想为此编写一个完整的单元测试类(除非你当然感觉它是:P)但是一个简单的样本就可以了。我假设我需要“模拟”IVendorBriefRepository以便在构建我的控制器时可以将它传递给构造函数(不要与mvc控制器混淆),但我不知道该怎么做。使用我自己的一些代码的示例将真正帮助我开始。

提前致谢!

2 个答案:

答案 0 :(得分:37)

例如,像这样的东西会测试DeleteVendorBrief。

Mock<IVendorBriefRepository> mock = new Mock<IVendorBriefRepository>();

VendorBriefController controller = new VendorBriefController(mock.Object);

VendorBrief brief = new VendorBrief();

controller.DeleteVendorBrief(brief);

mock.Verify(f=>f.DeleteVendorBrief(brief));
mock.Verify(f=>f.SaveChanges());

答案 1 :(得分:1)

如果您不需要为 Mocked 对象设置任何特殊行为,而只想将伪造的对象传递到简单的单元测试中,您还可以使用较短的 Mock.Of<T>() 语法。

这里的好处是您无需记住传入 .Object

以 Brook 的代码为参考:

Mock<IVendorBriefRepository> mock = Mock.Of<IVendorBriefRepository>();

VendorBriefController controller = new VendorBriefController(mock);
//...

特别是如果您的代码使用依赖注入并传入很多的依赖项,这种语法会使代码更清晰易读。