繁体   English   中英

使用nSubstitute时未调用抽象的Dispose方法

[英]Abstracted Dispose Method not called when using nSubstitute

我有这个基础(抽象)类:

public abstract class StreamWriterBuilderService : IStreamWriterService
{
    private Stream fs;
    private StreamWriter stream;

    public void WriteLine(
        string stringToWrite )
    {
        if ( stream == null )
        {
            throw new InvalidOperationException( "Tried to call WriteLine on an uninitialised StreamWriterBuilderService" );
        }

        stream.WriteLine( stringToWrite );
        Flush();
    }

    public void Flush()
    {
        if ( stream == null )
        {
            throw new InvalidOperationException( "Tried to call Flush on an uninitialised StreamWriterBuilderService" );
        }

        stream.Flush();
    }

    public void Initialise(
        string filePath )
    {
        Contract.Requires<ArgumentNullException>( filePath != null );

        fs = File.Open( filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite );
        stream = new StreamWriter( fs );
        WriteLine("Initialised");
        Initialised = true;
    }

    public bool Initialised { get; private set; }

    #region Dispose Implementation

    ~StreamWriterBuilderService()
    {
        Dispose( false );
        Debug.WriteLine( false, "This StreamWriterBuilderService object was not disposed of" );
    }

    private bool _isDisposed;

    public virtual void Dispose()
    {
        Dispose( true );
        GC.SuppressFinalize( this );
    }

    protected virtual void Dispose(
        bool disposing )
    {
        if ( _isDisposed )
            return;

        if ( disposing && Initialised )
        {
            stream.Dispose();
            fs.Dispose();
            stream = null;
            fs = null;
        }

        _isDisposed = true;
    }

    #endregion Dispose Implementation
}

我正在用以下方法进行单元测试:

    protected readonly string TargetFilePath = Path.GetTempFileName();
    protected const string Header = "Initialised";

    protected override void SetContext()
    {
        SUT = Substitute.For<StreamWriterBuilderService>();
    }

和...

    private string fileContents;
    private const string TestString = @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!£$%^&*()+~@?><|¬";

    protected override void Because()
    {
        base.Because();
        SUT.Initialise( TargetFilePath );
        SUT.WriteLine( TestString );
        SUT.Flush();
        SUT.Dispose();
        fileContents = File.ReadAllText( TargetFilePath );
    }

我遇到的麻烦是:

SUT.Dispose();

实际上没有在抽象类中调用我的Dispose方法,因为它被声明为虚拟方法。 如果我删除了虚方法,那么代码将被播放。 但是,我需要将虚拟方法保留在那里,因为我需要在解决方案中的其他地方覆盖...

您应该使用:

var SUT = Substitute.ForPartsOf<StreamWriterBuilderService>();

这使您可以很好地控制要替换的特定内容。 因此,默认情况下,不会替换您的Dispose方法。

另外,我的建议(针对此特定方案)将是构建您自己的StreamWriterBuilderServiceForTesting类(该类继承自StreamWriterBuilderService )。 因为不涉及NSubstitute,所以您可以根据自己的喜好定义其行为。

当您substitute的类时, 虚拟方法将被替换。 您可能只想部分替换Dispose(bool)

有关部分替代品的文档

第二段在这里

对于初学者来说,NSubstitute只能与该类的虚拟成员一起使用,因此该类中的任何非虚拟代码都将实际执行!

也就是说,虚拟方法将不会执行。

我将创建派生类型以进行测试,以删除abstract ,然后进行测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM