Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing COM对象的可测试设计_Unit Testing_Com_Interface_Implementation_Factory - Fatal编程技术网

Unit testing COM对象的可测试设计

Unit testing COM对象的可测试设计,unit-testing,com,interface,implementation,factory,Unit Testing,Com,Interface,Implementation,Factory,当用于完成任务的组件可以是COM组件或.NET组件时,设计测试和可扩展性的好方法是什么?完全包装COM组件并提取接口有意义吗?这是COM组件上的一个简单、完全人为设计的RCW接口,其中“abc”是组件制造商的首字母缩写: public interface IComRobot { void abcInitialize(object o); void abcSet(string s, object o); void abcBuild(); void abcExi

当用于完成任务的组件可以是COM组件或.NET组件时,设计测试和可扩展性的好方法是什么?完全包装COM组件并提取接口有意义吗?这是COM组件上的一个简单、完全人为设计的RCW接口,其中“abc”是组件制造商的首字母缩写:

public interface IComRobot
{
    void abcInitialize(object o);

    void abcSet(string s, object o);

    void abcBuild();

    void abcExit();
}
对我来说,组件的提供者选择在所有方法前面加上表示其公司的前缀这一事实有点令人恼火。问题是,我想定义执行相同操作的其他机器人组件,但底层实现不同。对于机器人制造者来说,必须实现“abcAnything”是完全令人困惑的

我应该如何用这样一个简单的实现来构建一个机器人工厂呢

public class RobotFactory
{
    public static IRobot Create(int i) 
    {
        // // problem because ComRobot implements IComRobot not IRobot
        if (i == 0) return new ComRobot();
        if (i == 1) return new AdvancedRobot();
        return new SimpleRobot();        
    }
}
我是否应该咬紧牙关,在接口中接受abc前缀,从而混淆机器人实现者?我是否应该强制机器人消费者了解他们何时使用COM机器人?这些似乎都不理想。我正在考虑一个额外的抽象层次(可以解决所有问题,对吗?)。大概是这样的:

public interface IRobot : IDisposable
{
    void Initialize(object o);

    void Set(string s, object o);

    void Build();

    void Exit();
}

public class ComRobotWrapper: IRobot
{
    private readonly IComRobot m_comRobot;

    public ComRobotWrapper()
    {
        m_comRobot = ComRobotFactory.Create();    
    }

    public void Initialize(object o)
    {
        m_comRobot.abcInitialize(o);
    }

    public void Set(string s, object o)
    {
        m_comRobot.abcSet(s, o);
    }

    public void Build()
    {
        m_comRobot.abcBuild();
    }

    public void Exit()
    {
        m_comRobot.abcExit();
    }


    public void Dispose()
    {
        //...RELEASE COM COMPONENT
    }
}

public class ComRobotFactory
{
    public static IComRobot Create()
    {
        return new ComRobot();
    }
}    
然后我会像这样修改和使用机器人工厂:

public class RobotFactory
{
    public static IRobot Create(int i) 
    {
        if (i == 0) return new ComRobotWrapper();
        if (i == 1) return new AdvancedRobot();
        return new SimpleRobot();        
    }
}

public class Tester
{
    // local vars loaded somehow

    public void Test()
    {
        using (IRobot robot = RobotFactory.Create(0))
        {
            robot.Initialize(m_configuration);
            robot.Set(m_model, m_spec);
            robot.Build();
            robot.Exit();
        }
    }
}

我对这种方法的观点很感兴趣。你推荐另一种方法吗?我真的不想采用DI框架,所以这超出了范围。可测试性是否存在缺陷?我很感激你花时间考虑这个漫长的问题。您正在创建一个适合您的域/应用程序的接口,并以第三方组件的形式实现它。

这在我看来很合适。您正在创建一个适合您的域/应用程序的接口,并用第三方组件实现它。

我认为您的“接口中的非abc前缀”解决方案和“com接口的适配器实现”是一个很好的解决方案。您已经按照我的方式解决了这个问题。我认为您的“接口中的非abc前缀”解决方案和“com接口的适配器实现”是一个很好的解决方案。你已经像我那样解决了这个问题。