xUnit 用假的替换第三方 class 实例

xUnit to replace thirdParty class instance with a fake one

我的部分 class 将对象初始化为 MLM(这需要大量设置和安装)我需要的是替换它 用一个假对象以简单的方式做同样的事情,

例如如何使用假对象测试以下代码

// LMXProxyServerClass is the library in which need a lot of installation 
private readonly LMXProxyServerClass lmxProxyServer; 

这是我在

中使用的方法之一的示例
private bool CreateBindingWithoutPropagate(string attributeName, bool supervisory)
{
    bool creatingBindingResult = false;

    lock (mxAccessProxyLock)
    {

        if (!bindings.ContainsKey(attributeName))
        {
            try
            {
                logger.Debug("Adding item " + attributeName + " to bindings, not in list so add.");

                // Add the handle to the mapping
                lmxHandleToAttributeNameMapping.Add(attributeBinding.MxAttributeHandle, attributeName);

                if (supervisory)
                {
                     lmxProxyServer.DoSOmethingElse(yyyyyyyyyyyyyyyyyyyyyyy);
                    logger.Info(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx);
                }
                else
                {

                    lmxProxyServer.DoSOmething(xxxxxxxx);
                    logger.Info(xxxxxxxxxxx);
                }

                // Add the binding to the list of bindings.
                bindings.Add(attributeName, attributeBinding);

                logger.Info("Creating binding for: " + attributeName);

                creatingBindingResult = true;

            }
            catch (System.UnauthorizedAccessException unauthorizedAccessException)
            {

                logger.Error("xxxxxxxxxxx", attributeName);
                throw ConvertExceptionToFault(unauthorizedAccessException);

            }
            catch (Exception ex)
            {
                throw ConvertExceptionToFault(ex);
            }
        }
    }

    return creatingBindingResult;
}

这个库是第三方的,所以我无法控制它,所以在测试中我需要用假的替换这个对象,这样我就不会在基本代码中做太多改动,也可以简化其他的测试零件

将代码与第 3 方实现问题紧密耦合使得很难单独对代码进行单元测试。

而是将第 3 方实现问题封装在一个抽象中,可以在测试时根据需要进行模拟。

例如,创建第 3 方依赖项的抽象,仅公开您的代码所需的内容。

public interface ILMXProxyServer {
    void DoSOmethingElse(...);
    void DoSOmething(...);
    //...
}

并通过构造函数注入显式注入依赖项。

public class MyClass {
    private readonly ILMXProxyServer lmxProxyServer; 

    public MyClass(ILMXProxyServer lmxProxyServer) {
        this.lmxProxyServer = lmxProxyServer;
    }

    //...other code omitted for brevity
}

方法保持不变,因为它们将调用抽象的公开成员。

运行次执行会wrap/encapsulate第3方依赖

public class MyLMXProxyServerWrapper : ILMXProxyServer {
    // LMXProxyServerClass is the library in which need a lot of installation 
    private readonly LMXProxyServerClass lmxProxyServer; 


    public void DoSOmething(Something xxxxxxx){
         lmxProxyServer.DoSOmething(xxxxxxxx);
    }

    //...code omitted for brevity
}

通过重构,代码现在可以更加灵活 mock/fake 在使用您选择的模拟框架或通过滚动您自己的特定于测试的实现进行隔离测试时代理服务器。