为什么Moq框架无法看到属于模拟对象类的方法?

时间:2014-11-08 10:18:07

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

我的代码中有以下Entity Framework DBContext的子类,名为BlahBlahDataContext。 我们需要使用Moq Framework来模拟子类以进行测试。

namespace BlahBlahExample.Data
{
    using System;
    using System.Linq;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using AutoMapper;
    using BlahBlah.Framework.Audit;
    using BlahBlah.Framework.Audit.Contracts;
    using BlahBlah.Framework.Core.Contracts;
    using BlahBlah.Framework.Core.Strategy;
    using BlahBlah.Framework.EntityFramework;
    using BlahBlahExample.Domain.Objects;

public partial class BlahBlahDataContext : DbContext, IRepositoryFactory, IDataContext
{
        private readonly IAuditMappingProvider _providerAuditMapping;
        private IStrategyContainer _strategyContainer;

    public BlahBlahDataContext()
        : base("name=NorthwindModel")
    {
            Database.Log = Log;

    } // end empty constructor

    public BlahBlahDataContext(IAuditMappingProvider providerAuditMapping)
    {
        _providerAuditMapping = providerAuditMapping;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    private void BindAuditStrategyDynamic(dynamic repository)
    {
        BindAuditStrategy(repository);
    }

                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Category> Categories { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<CustomerDemographic> CustomerDemographics { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Customer> Customers { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Employee> Employees { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Order_Detail> Order_Details { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Order> Orders { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Product> Products { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Region> Regions { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Shipper> Shippers { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Supplier> Suppliers { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Territory> Territories { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<Account> Accounts { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<AccountRole> AccountRoles { get; set; }
                    // codeStringGenerator.DbSet(entitySet).Replace("_", "")
    public virtual DbSet<AccountRoleMap> AccountRoleMaps { get; set; }



        private void BindAuditStrategy(IRepository<CustomerDemographic> repository)
        {
            Mapper.CreateMap<CustomerDemographic, CustomerDemographicAudit>();

            var auditStrategy = new AuditStrategy<CustomerDemographic, CustomerDemographicAudit>(
                this,
                new BlahBlahAuditContext(),
                _providerAuditMapping,
                Mapper.Map<CustomerDemographicAudit>);

            auditStrategy.Attach(repository);
        }


        private void BindAuditStrategy(IRepository<Customer> repository)
        {
            Mapper.CreateMap<Customer, CustomerAudit>();

            var auditStrategy = new AuditStrategy<Customer, CustomerAudit>(
                this,
                new BlahBlahAuditContext(),
                _providerAuditMapping,
                Mapper.Map<CustomerAudit>);

            auditStrategy.Attach(repository);
        }


        private void BindAuditStrategy(IRepository<Order> repository)
        {
            Mapper.CreateMap<Order, OrderAudit>();

            var auditStrategy = new AuditStrategy<Order, OrderAudit>(
                this,
                new BlahBlahAuditContext(),
                _providerAuditMapping,
                Mapper.Map<OrderAudit>);

            auditStrategy.Attach(repository);
        }


        public virtual IRepository<TEntity> CreateRepository<TEntity>(IRepository useRepositoryContext = null) where TEntity : class
        {
            var context = (useRepositoryContext == null ? new BlahBlahDataContext() : useRepositoryContext.Context as IDataContext) ?? new BlahBlahDataContext();

            var repository = new EntityFrameworkRepository<TEntity>(context);

            if (_providerAuditMapping.Classes.Any(λ => λ.EntityType == typeof (TEntity)))
            {
                BindAuditStrategyDynamic(repository);
            }

            return repository;
        }

        public IStrategyContainer StrategyContainer
        {
            get
            {
                return _strategyContainer ?? (_strategyContainer = new BaseStrategyContainer());
            }
        }

        public event EventHandler<string> OnLog;
        private void Log(string message)
        {
            if (OnLog != null)
            {
                OnLog(this, message);
            }
        }
    }
}

我们需要使用Moq Framework mock来测试子类。

在我的测试代码中,我们有以下代码:

Mock<BlahBlahDataContext> fctry = new Mock<BlahBlahDataContext>(mappingProvider);

但是,如果我尝试在前一行之后立即输入以下行,则无法识别CreateRepository方法

fctry.CreateRepository

为什么moq的Mock没有看到CreateRepository方法?

1 个答案:

答案 0 :(得分:4)

Mock<T>为您提供了一个使用T方法模拟的实际Setup()类的包装器:

var service = new Mock<IService>();
service.Setup(s => s.GetData()).Returns("test data");

之后,您可以通过service.Object属性访问实际的模拟对象:

IService mocked = service.Object;
string data = mocked.GetData(); // returns "test data" string