如何重写代码以避免在单元测试期间调用外部dll

How to rewrite code to avoid call to external dll during unit test

有class个驱动程序,它在构造函数中调用静态extern方法。更改体系结构以便能够对驱动程序方法进行单元测试的最佳方法是什么。

public class Driver
{
    [DllImport("Driver.dll")]
    private static extern IntPtr CreateDriver();

    // Pointer to C++ Driver object
    internal IntPtr DriverPtr; // this for integration tests

    public Driver()
    {
        DriverPtr = CreateDriver();
    }

    public int SomeMethod(int a) // test only this method
    {
        return a + 1;
    }
}

方法有很多,就看你想做什么了。

例如,您可以创建一个带有额外参数的虚拟构造函数并且不执行调用:

public Driver(bool dummy){ }

或者将构造函数更改为做注释,然后有一个 Init() 函数:

public Driver(){ } //Can be removed, left for example clarity

public void Init(){ DriverPtr = CreateDriver(); }

您的故事并不完全清楚,但我认为您是在询问如何在不必与实际驱动程序 DLL 交互的情况下测试代码。不清楚您是否要在构造函数中使用分配给 DriverPtr 的值。

您可以通过将静态方法移动到实例 class 中来解决此问题,连接该实例 class 并在测试期间对其进行模拟。

接口:

public interface IDriverProvider
{
    IntPtr Create();
}

实施:

public class DriverProvider : IDriverProvider
{
    [DllImport("Driver.dll")]
    private static extern IntPtr CreateDriver();

    public IntPtr Create()
    {
        return CreateDriver();
    }
}

然后将其注入您的使用 class:

public class Driver
{
    internal IntPtr DriverPtr;

    public Driver(IDriverProvider driverProvider)
    {
        DriverPtr = driverProvider.Create();
    }

    public int SomeMethod(int a) // test this method
    {
        return a + 1;
    }
}

现在您可以测试您的 class:

// Arrange
var driverProviderMock = new Mock<IDriverProvider>();   
var driver = new Driver(driverProviderMock.Object);

// Act
driver.SomeMethod();

// Assert
driverProviderMock.Verify(d => d.Create());