开发者

How to File.Exists in Nunit Test

I have a method which tests for the existence of a file prior to carrying out some manipulation of file content as follows:

Private Sub AddHeaderToLogFile()
    ''#Only if file does not exist
    If Not File.Exists(_logPath) Then
        Dim headerLogger As Logger
        headerLogger = LogManager.GetLogger("HeaderLogger")
        ''#Use GlobalDiagnosticContext in 2.0, GDC in pre-2.0
        NLog.GlobalDiagnosticsContext.Set("appName", _appName)
        NLog.GlobalDiagnosticsContext.Set("fileVersion", _fileVersion)
        NLog.GlobalDiagnosticsContext.Set("logId", 0)
        headerLogger.Info("")
    End If
End Sub

The idea is that if the file does not exist, then the file is generated by calls to the NLog logger instance, at which point the file is created and the specified header info is inserted. The method works fine from the application itself, however I have a simple NUnit test which implements a test method to verify that the file is created and populated as expected. When I step through with the debugger, I find that '_logPath' is set to:

D:\Documents and Settings\TE602510\Local Settings\Temp\nunit20\ShadowCopyCache\4288_634286300896838506\Tests_-1937845265\assembly\dl3\7cdfe61a\aa18c98d_f0a1cb01\logs\2010-12-22.log

Unfortunately, despite the fact that the file DOES exist, the call to File.Exists returns false. From earlier viewing of the config path the above path would appear to be correct for these NUnit tests. Does anybody have a clue what is happening here a开发者_JAVA百科nd what I need to do to get the desired result? The pathname to the log file as per the XP file system is:

D:\Documents and Settings\TE602510\My Documents_VSSWorkArea\PsalertsIp\Tests\bin\Debug\logs

Kind Regards

Paul J.


Don't use File.Exists!

The file system is volatile, and so existence (or not) of the file you're looking for could change in between when you check and when you act on the results. Additionally, File.Exists does nothing to determine whether you have the correct permissions for the file in question.

Instead, what you want to do here is just try to correctly open the file, like so:

Try
    Using fs As IO.FileStream = IO.File.Open(_logPath, FileMode.CreateNew)

    End Using
Catch ex AS IOException 
    ''# This will be thrown if the file already exists - just swallow it
    ''# If you also want to handle IOExceptions while working on the file,
    ''#  place another try/catch inside the using block
End Try

File.Exists should only be used when the existence of a file by itself has meaning, but the file will never actually be read or written. For example, some main frame systems will create and destroy files to indicate locks, or to signal the completion of a job.


It might be a permission issue. From MSDN, File.Exists(path) returns:

true if the caller has the required permissions and path contains the name of an existing file; otherwise, false. This method also returns false if path is a null reference (Nothing in Visual Basic), an invalid path, or a zero-length string. If the caller does not have sufficient permissions to read the specified file, no exception is thrown and the method returns false regardless of the existence of path.

EDIT Here are two methods that will try to get the ACLs of a directory/file. It's possible that the way that NUnit it being invoked that the permissions are different.

Private Shared Function DoesFileExist(ByVal file As String) As Boolean
    Try
        Dim FI As New System.IO.FileInfo(file)
        Dim AC = FI.GetAccessControl()              'This method will fail if the file is not found'
        Return True
    Catch ex As System.IO.FileNotFoundException     'FNF error should be thrown if it does not exist'
        Return False
    Catch ex As Exception
        'If you do not have permission to read the permissions this might throw, too.'
        'Of course, in that situation that means that the file exists so we should'
        'probably return True here, too. For debugging I am still throwing though.'
        Throw ex
    End Try
End Function
Private Shared Function DoesDirectoryExist(ByVal dir As String) As Boolean
    Try
        Dim DI As New System.IO.DirectoryInfo(dir)
        Dim AC = DI.GetAccessControl()               'This method will fail if the directory is not found'
        Return True
    Catch ex As System.IO.DirectoryNotFoundException 'DNF error should be thrown if it does not exist'
        Return False
    Catch ex As Exception
        'If you do not have permission to read the permissions this might throw, too.'
        'Of course, in that situation that means that the directory exists so we should'
        'probably return True here, too. For debugging I am still throwing though.'
        Throw ex
    End Try
End Function
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜