如何为“模范"方法从多个代表分配/选择? [英] How to assign/opt from multiple delegates for a 'moled' method?

查看:87
本文介绍了如何为“模范"方法从多个代表分配/选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在等待VS 2010许可证时,我目前正在从外部检查Moles,不知道Moles是否允许我进行以下操作:

I am currently examining Moles from the outside while I wait for my VS 2010 license, and I wonder whether Moles allows me to:

  1. 是否可以在测试夹具设置级别上为正在被模拟的方法配置多个摩尔委托?
  2. 在我的测试用例中运行时切换,对于即将被隔离的moled方法的即将进行的调用,必须调用哪个mole委托?

有任何提示吗?

推荐答案

最佳答案:

与在同一个方法中使用两个存根相比,在绕行方法中包括门控逻辑要容易得多,并且要有意义得多!例如, MyMethod 从磁盘上的三个不同文件读取数据,每个文件都需要返回不同的模拟数据.我们可以绕过 System.IO.File.OpenRead 并通过分析 OpenRead 的输入参数来确定返回值:

Best Answer:

It is much easier and makes far more sense to include gating logic in the detour method, than using two stubs for the same method! For example, MyMethod reads data from three different files on disk, each requiring different mock data to be returned. We may detour System.IO.File.OpenRead and gate the return value by analyzing the input parameters of OpenRead:

测试方法:

[TestMethod]
[HostType("Moles")]
public void Test()
{
    System.IO.Moles.MFile.OpenReadString = filePath => {
        var mockStream = new System.IO.FileStream();
        byte[] buffer;
        switch (filePath)
        {
            case @"C:\DataFile.dat":
                mockStream.Write(buffer, 0, 0); // Populate stream
                break;
            case @"C:\TextFile.txt":
                mockStream.Write(buffer, 0, 0); // Populate stream
                break;
            case @"C:\LogFile.log":
                mockStream.Write(buffer, 0, 0); // Populate stream
                break;
        }
        return mockStream;
    };


    var target = new MyClass();
    target.MyMethod();
}

目标类型:

using System.IO;
public class MyClass
{
    public void MyMethod()
    {
        var fileAData = File.OpenRead(@"C:\DataFile.dat");
        var fileBData = File.OpenRead(@"C:\TextFile.txt");
        var fileCData = File.OpenRead(@"C:\LogFile.log");
    }
}


直接回答您的问题:

是#1 :为每个绕行实例化一种类型,然后将每种类型用于所需的行为.并且,是#2 :对一个痣类型的一个实例或另一个实例进行操作.这需要添加方法输入参数或类构造函数注入.


Direct Answer to Your Questions:

Yes to #1: instantiate one type for each detour, and then use each for the desired behavior. And, yes to #2: act upon one instance of the mole type or the other. This requires addition of method input parameters or class constructor injection.

例如, MyMethod 从磁盘读取三个数据文件,您需要传回三个不同的数据模拟. MyMethod 需要三个参数,这是一个公开的解决方案. (请注意,输入参数是FileInfo类型;因为System.IO> File是静态的,无法实例化:例如:

For example, MyMethod reads three data files from disk, and you need to pass back three different data mocks. MyMethod requires three parameters, an overtly intrusive solution. (Note input parameters are FileInfo type; because, System.IO>File is static and can not be instantiated: For example:

测试方法:

[TestMethod]
[HostType("Moles")]
public void Test()
{
    var fileInfoMoleA = new System.IO.Moles.MFileInfo();
    fileInfoMoleA.OpenRead = () => { return new FileStream(); };

    var fileInfoMoleB = new System.IO.Moles.MFileInfo();
    fileInfoMoleB.OpenRead = () => { return new FileStream(); };

    var fileInfoMoleC = new System.IO.Moles.MFileInfo();
    fileInfoMoleC.OpenRead = () => { return new FileStream(); };

    var target = new MyClass();
    target.MyMethod(fileInfoMoleA, fileInfoMoleB, fileInfoMoleC);
}

目标类型:

using System.IO;
public class MyClass
{
    // Input parameters are FileInfo type; because, System.IO.File
    // is a static class, and can not be instantiated.
    public void MyMethod(FileInfo fileInfoA, FileInfo fileInfoB, FileInfo fileInfoC)
    {
        var fileAData = fileInfoA.OpenRead();
        var fileBData = fileInfoB.OpenRead();
        var fileCData = fileInfoC.OpenRead();
    }
}


更新:

响应@Chai的评论,可以在测试项目中创建一些通用方法,这些方法可以称为绕道绕行"委托.例如,您可能希望编写任何单元测试都可以引用的通用方法,该方法可以设置各种预先配置的方案.以下示例显示如何使用参数化方法.发挥创造力-它们只是方法调用!


UPDATE:

In response to @Chai comment, it is possible to create common methods, within the test project, that may be referenced as the mole detour delegate. For example, you may wish to write a common method that may be referenced by any unit test, that sets up a variety of pre-configured scenarios. The following example displays how a parameterized method could be used. Get creative -- they're just method calls!

目标类型:

namespace PexMoleDemo
{
    public class MyClass
    {
        private MyMath _math;
        public MyClass()
        {
            _math = new MyMath() { left = 1m, right = 2m };
        }

        public decimal GetResults()
        {
            return _math.Divide();
        }
    }

    public class MyOtherClass
    {
        private MyMath _math;
        public MyOtherClass()
        {
            _math = new MyMath() { left = 100m, right = 200m };
        }

        public decimal Divide()
        {
            return _math.Divide();
        }
    }

    public class MyMath
    {
        public decimal left { get; set; }
        public decimal right { get; set; }

        public decimal Divide()
        {
            return left / right;
        }
    }
}

测试方法: ArrangeScenarios()通过打开枚举参数来设置绕行路线.这样可以在许多测试中以DRY方式建立相同的场景.

TEST METHODS: ArrangeScenarios() sets up mole detours, by switching on the enumeration parameter. This allows the same scenarios to be erected, in a DRY manner, throughout many tests.

using System;
using Microsoft.Moles.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PexMoleDemo;
[assembly: MoledAssembly("PexMoleDemo")]

namespace TestProject1
{
    [TestClass()]
    public class ProgramTest
    {
        public enum Scenarios
        {
            DivideByZero,
            MultiplyInsteadOfDivide
        }

        private void ArrangeScenario(Scenarios scenario)
        {
            switch (scenario)
            {
                case Scenarios.DivideByZero:
                    PexMoleDemo.Moles.MMyMath.AllInstances.rightGet = 
                        instance => { return 0m; };
                    break;
                case Scenarios.MultiplyInsteadOfDivide:
                    PexMoleDemo.Moles.MMyMath.AllInstances.Divide = 
                        instance => { return instance.left * instance.right; };
                    break;
                default:
                    throw new NotImplementedException("Invalid scenario.");
            }
        }

        [TestMethod]
        [HostType("Moles")]
        [ExpectedException(typeof(DivideByZeroException))]
        public void Test1()
        {
            ArrangeScenario(Scenarios.DivideByZero);
            var target = new PexMoleDemo.MyClass();

            var math = new PexMoleDemo.MyMath() { left = 1, right = 2 };
            var left = math.left;
            var right = math.right;


            var actual = target.GetResults();
        }

        [TestMethod]
        [HostType("Moles")]
        public void Test2()
        {
            ArrangeScenario(Scenarios.MultiplyInsteadOfDivide);
            // Perform some sort of test that determines if code breaks
            // when values are multiplied instead of divided.
        }

        [TestMethod]
        [HostType("Moles")]
        [ExpectedException(typeof(DivideByZeroException))]
        public void Test3()
        {
            ArrangeScenario(Scenarios.DivideByZero);
            var target = new PexMoleDemo.MyOtherClass();

            var math = new PexMoleDemo.MyMath() { left = 1, right = 2 };
            var left = math.left;
            var right = math.right;


            var actual = target.Divide();
        }

        [TestMethod]
        [HostType("Moles")]
        public void Test4()
        {
            ArrangeScenario(Scenarios.MultiplyInsteadOfDivide);
            // Perform some sort of test that determines if code breaks
            // when values are multiplied instead of divided.
        }
    }
}

这篇关于如何为“模范"方法从多个代表分配/选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆