zoukankan      html  css  js  c++  java
  • 第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

  • 相关阅读:
    LeetCode-Pascal's Triangle
    macOS Sierra 10.12版本 显示隐藏文件
    Android主页导航:fragment+viewpager
    (转)Android工程出现 java.lang.NoClassDefFoundError错误解决方法
    Android Studio安装以及Fetching android sdk component information超时的解决方案
    Android项目使用Ant多渠道打包(最新sdk)
    eclipse或Myeclipse中web项目没有run on server时怎么办?
    mysq查询语句包含中文以及中文乱码,字符集 GBK、GB2312、UTF8的区别
    论HTML的div、span和label的区别
    斐波那契数列
  • 原文地址:https://www.cnblogs.com/wjs5943283/p/4611633.html
Copyright © 2011-2022 走看看