第6章 MVC基本工具

DI容器、单元测试框架、模仿工具

一、Ninject

Ninject的目的:解决对接口的实现进行实例化,但需要的实现细节又不在控制器代码中。

Ninject使用C#的类型参数创建了一种关系:将想要使用的接口设置为Bind方法的类型参数,并在返回的结果上调用To方法。

笔记:

  1.Ninject条件绑定常用方法:

    When(predicate)      //当predicate结果为true时,实施绑定。(predicate一个lambda表达式)

    WhenclassHas<T>()    //当被注入的类以注解属性进行注释,且其类型为T时,实施绑定([T])

    WhenInjectedInfo<T>()  //当要被注入的类是类型T时,实施绑定

  2.使用Ninject:

    1.创建依赖解析器(Infrastructure)    

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Essentialtools.Models;
using Ninject;

namespace Essentialtools.Infrastructure
{
    public class NinjdectDependencyResolver:IDependencyResolver
    {
        private IKernel kernel;

        public NinjdectDependencyResolver()
        {
            //创建Ninject内核的实例
            kernel = new StandardKernel();
            AddBindings();
        }

        public object GetService(Type serviceType)
        {
            return kernel.TryGet(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return kernel.GetAll(serviceType);
        }

        //建立接口与实现类之间的关系
        private void AddBindings()
        {
            //构造器
            kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
            //属性
           // kernel.Bind<IDiscoutnHelper>().To<DefaultDiscoutnHelper>().WithPropertyValue("DiscountSize",20M);
            //构造器参数
            kernel.Bind<IDiscoutnHelper>().To<DefaultDiscoutnHelper>().WithConstructorArgument("discountParam", 30M);
            //条件绑定
            kernel.Bind<IDiscoutnHelper>().To<FlexibleDiscountHelper>().WhenInjectedInto<LinqValueCalculator>();
           
        }
    }
}

     2.注册依赖解析器(Global.asax)  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using Essentialtools.Infrastructure;

namespace Essentialtools
{
    // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
    // 请访问 http://go.microsoft.com/?LinkId=9394801
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            //注册依赖解析器
            DependencyResolver.SetResolver(new NinjdectDependencyResolver());

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
    }
}

    3.重构控制器

.................
//构造器
private IValueCalculator calc; public HomeController(IValueCalculator calcParam) { calc = calcParam; } .................

二、单元测试: 

  引入原命名空间到单元测试中。

  “准备\动作\断言”模式。

  静态的Assert方法

方法 描述

AreEqual<T>(T,T)

AreEqual<T>(T,T,string)

断言两个类型T的对象有相同的值

AreNotEqual<T>(T,T)

AreNotEqual<T>(T,T,string)

断言两个类型T的对象的值不相等

AreSame<T>(T,T)

AreSame<T>(T,T,string)

断言两个变量指向相同的对象

AreNotSame<T>(T,T)

AreNotSame<T>(T,T,string)

断言两个变量指向不同的对象

Fail()

Fail(string)

失败断言 -无条件检查

Inconclusive()

Inconclusive(string)

指示最终不能建立单元测试的结果

IsTrue(bool)

IsTrue(bool,string)

断言一个返回结果的值为True

IsFalse(bool)

IsFalse(bool,string)

断言一个返回结果的值为false

IsNull(object)

IsNull(object,string)

断言一个变量未被分配一个对象的引用

IsNotNull(object)

IsNotNull(object,string)

断言一个变量被分配了一个对象的引用

IsInstanceOfType(object,Type)

IsInstanceOfType(object,Type,string)

断言一个对象是指定的类型,或派生于指定的类型

IsNotInstanceOfType(object,Type)

IsNotInstanceOfType(object,Type,string)

断言一个对象不是指定的类型

ExpectedException属性成员:只有当单元测试抛出ExceptionType参数指定类型的异常时,该断言才是成功的。不需要try...catch。

    [ExpectedException(typeof(ArgumentOutOfRangeException))]

三、Moq:模仿对象

  步骤:

    1.用Mock创建模仿对象

    2.用Setup方法建立模仿对象的行为

    3.用It类设置行为的参数

    4.用Return指定行为的返回类型

    5.用lambda表达式在Return方法中建立具体的行为 

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

  mock.Setup(m=>m.ApplyDiscount(It.IsAny<decimal>())).Returns<decimal>(total=>total);

  var target=new LinqValueCalculator(mock.Object);

 It类的静态方法

方法 描述
Is<T>(predicate) 指定类型T的值,使“predicate谓词”返回true
IsAny<T>() 指定类型T的值为任意值
IsInRange<T>(min,max,kind)

如果参数介于定义值之间,而且是T类型的,则匹配。kind枚举值:Inclusive(包括),Exclusive(排除)

IsRegex(expr) 如果参数是一个字符串,而且符合指定的正则表达式则匹配

 

  模仿抛出异常:

  mock.Setup(m=>m.ApplyDiscount(It.Is<decimal>(v=>v==0))).Throws<System.ArgumentOutRangeException>();

单元测试 这个是思维方法和开发风格决定的。  

源码:http://yunpan.cn/cQ9QEgtrWXaS9 访问密码 bbd2

posted @ 2015-07-01 22:01  小居工作室  阅读(364)  评论(2编辑  收藏  举报