Typemock:从接口用存根替换类时出错

本文关键字:替换 出错 存根 接口 Typemock | 更新日期: 2023-09-27 18:37:07

我正在使用Typemock进行一些单元测试。就我而言,我正在为执行平面文件数据处理的程序编写测试。为了对该程序进行单元测试,我编写了一些存根类,这些类实现了与实际版本相同的接口,但不是写入文件系统,而是包含它们写入的内部字符串。

现在我试图让 Typemock 在测试中用存根变体替换类的实际版本,但它给了我以下错误:System.InvalidOperationException :可为空的对象必须具有值。

这是我尝试用我的存根替换的实际版本(包含更多,但错误不在那些行上):

public class BatchRepository : IBatchRepository
    {
        private readonly string _connectionStringName;
        public BatchRepository(string connectionStringName) <-- Error triggers on this line
        {
            _connectionStringName = connectionStringName;
        }
}

存根类:

public class BatchRepositoryStub : IBatchRepository
{
    private readonly string _connectionStringName;
    public BatchRepositoryStub(string connectionStringName)
    {
        _connectionStringName = connectionStringName;
    }
}
测试

类和我的测试方法:

[TestClass]
public class InputTest
{
    // Variables
    private IBatchRepository _batchRepository;
    private ICommunicatieproductRepository _communicatieproductRepository;
    // Constants
    private const string ConnectionStringName = "Test";
    private const string InputFileLocation = "Temp";
    private const string ArchiefLocation = "Temp";
    private const string ErrorLocation = "Temp";
    private const string LoggingLocation = "Temp";
    private const int BatchGrootte = 1000;
    // Use TestInitialize to run code before running each test 
    [TestInitialize()]
    public void Initialize()
    {
         _batchRepository = new BatchRepositoryStub(ConnectionStringName);
        _communicatieproductRepository = new CommunicatieproductRepositoryStub(ConnectionStringName);
    }
    [TestMethod]
    public void CMBatch_FDInput_NewFileErrorOnEmptyRelatienummer()
    {
        // Arrange
        Isolate.Swap.NextInstance<IBatchRepository>().With(_batchRepository);
        Isolate.Swap.NextInstance<ICommunicatieproductRepository>().With(_communicatieproductRepository);
        var inputFileProcessor = new InputFileProcessor(InputFileLocation, ArchiefLocation, ErrorLocation, LoggingLocation, BatchGrootte, ConnectionStringName);
      }

}

实际过程,这会触发错误

public class InputFileProcessor
    {
        private readonly string _inputFileLocation;
        private readonly string _archiefLocation;
        private readonly string _errorLocation;
        private readonly string _loggingLocation;
        private readonly int _batchGrootte;
        private readonly IBatchRepository _batchRepository;
        private readonly ICommunicatieproductRepository _communicatieproductRepository;
        /// <summary>
        /// Constructor
        /// </summary>
        public InputFileProcessor(string inputFileLocation, string archiefLocation, string errorLocation, string loggingLocation, int batchGrootte, string connectionStringName)
        {
            _inputFileLocation = inputFileLocation;
            _archiefLocation = archiefLocation;
            _errorLocation = errorLocation;
            _loggingLocation = loggingLocation;
            _batchGrootte = batchGrootte;
            _batchRepository = new BatchRepository(connectionStringName);
            _communicatieproductRepository = new CommunicatieproductRepository(connectionStringName);          
        }
}

当从 InputFileProcessor 的构造函数调用时,该错误在 BatchRepository 的构造函数上触发。起初我以为参数连接字符串名称为空,但事实并非如此。为什么它最终会走上这条线?使用交换实例方法,我认为它甚至不会到达那里,而是最终进入存根类。我认为我的交换实例实现有问题,但我无法弄清楚。

我知道像这样的测试可能不完全是单元测试的内容,但它是测试程序输出和输入的最简单方法。例如,我需要确保无效文件触发相应的错误。能够轻松更改输入使其更易于管理。

Typemock:从接口用存根替换类时出错

当然,

这可以用Typemock来完成:-)

使用 Swap.CallsOn(object) 将呼叫转发到存根(这些调用不需要可分配)。

请参阅示例:

// grab future
var futureInstanceHandle = Isolate.Fake.NextInstance<BatchRepository>();
// swap (ingoring type hiearchy)
Isolate.Swap.CallsOn(futureInstanceHandle).WithCallsTo(_batchRepositorystub);

在版本 8 中,您可以将 Fake.NextInstance<IBatchRepository> 用于接口!这将抓住实现IBatchRepository的第一个实例 - 很酷,嗯。

p.s 我在 Typemock 工作。

显然这是 Typemock 无法完成的事情。它本质上也是在测试太多的代码,这并不完全是单元测试。目前,我已经使用公司内部使用的变体重构了代码。