Events not being raised by FileSystemWatcher in an integration test? - events

I'm trying to run an integration test on my class to make sure an event i expect to be raised is raised:
'integration test not unit test
<TestMethod()>
Public Sub Change_Network_File_Causes_Event_To_Be_Raised()
Dim EventCalled As Boolean
Dim deployChk = New TRSDeploymentCheck("foo")
deployChk._localFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles\SameLocalGUIDFile.txt")
AddHandler deployChk.DeploymentNeeded, Sub() EventCalled = True
deployChk.NetworkFileLocation = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles\SameNetGUIDFile.txt")
ChangeNetworkFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles\SameNetGUIDFile.txt"))
Assert.IsTrue(EventCalled)
End Sub
Here is how i setup the FileSystemWatcher Object in my class:
Friend Property NetworkFileLocation As String
Set(value As String)
_netFileLoc = value
If File.Exists(value) Then
_watcher = New FileSystemWatcher(value.Replace(Path.GetFileName(value), String.Empty))
_watcher.EnableRaisingEvents = True
AddHandler _watcher.Changed, AddressOf OnNetworkFileChanged
End If
End Set
Get
Return _netFileLoc
End Get
End Property
Private Sub OnNetworkFileChanged(source As Object, e As FileSystemEventArgs)
If IsDeploymentNeeded() Then RaiseEvent DeploymentNeeded()
End Sub
I put a breakpoint in the OneNetworkFileChange sub. The breakpoint is never hit. I have verified the file is actually being changed in ChangeNetworkFile I even copied the code (except for hard coding the path) and copied it into a windows app which i ran during my unit test. It worked in my windows app. What am i missing here?

Finally figured it out after some testing. Well the reason EventCalled is never true above is because the "windows message pump" for the test is blocked. The event will be fired but only after the test completes (which of course is to late). So how do you fix it? Its kind of messy and i don't like it but i referenced System.Windows.Forms.dll & called Application.DoEvents()
'integration test not unit test
<TestMethod()>
Public Sub Change_Network_File_Causes_Event_To_Be_Raised()
Dim EventCalled As Boolean
Dim deployChk = New TRSDeploymentCheck("foo")
deployChk._localFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles\SameLocalGUIDFile.txt")
AddHandler deployChk.DeploymentNeeded, Sub() EventCalled = True
deployChk.NetworkFileLocation = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles\SameNetGUIDFile.txt")
ChangeNetworkFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles\SameNetGUIDFile.txt"))
Application.DoEvents()
Assert.IsTrue(EventCalled)
End Sub
Until some tells me a better way this appears to be the solution.

Probably its the filter (string.Empty) which apparently only looks at files without an extension (that's an assumption).
Try "*.*" or something like this:
_watcher = New FileSystemWatcher(value.Replace(Path.GetFileName(value), string.Concat("*.", Path.GetExtension(value))))

Related

How to call BlockInput in VBS

I have found on this site code for VBS to block user input. To simplify, code is:
Sub StopKeyMouse()
Set Def_DLL = DLL.DefineDLL("USER32")
Def_Proc = Def_DLL.DefineProc("BlockInput", vt_b1, vt_b1)
Set Lib = DLL.Load("USER32.DLL", "USER32")
Lib.BlockInput(True)
End Sub
Sub ResumeKeyMouse()
Set Def_DLL = DLL.DefineDLL("USER32")
Def_Proc = Def_DLL.DefineProc("BlockInput", vt_b1, vt_b1)
Set Lib = DLL.Load("USER32.DLL", "USER32")
Lib.BlockInput(False)
End Sub
Sub Test()
StopKeyMouse()
WScript.Sleep 1000
ResumeKeyMouse()
End Sub
Test()
When I run it, I get the error Object required: 'DLL'. Since the post is from 2004, I assume that VBS interaction with User32.dll has been changed.
I am missing a line with CreateObject, something like Set DLL = CreateObject("User32.dll").
Does anybody know what is correct code for script to work?
I have also found that it was possible to use
Set oAutoIt = CreateObject("AutoItX.Control")
oAutoIt.BlockInput "on"
But this is obsolete.
Is it possible to call BlockInput from VBS?
Thank you for any help.

VB 6 property does not retain value

I created a property in a class module called clsProperties:
Dim blnProduction As Boolean
Public Property Get IsProduction() As Boolean
IsProduction = blnProduction
End Property
Public Property Let IsProduction(ByVal vNewValue As Boolean)
blnProduction = vNewValue
End Property
I then call the Let statement from a form:
Private objPropertiesAs New clsProperties
'Determine if we're in production
If (Environ("computername")) = "WS0006" Then
objPropertiesAs.IsProduction = True
Else
objPropertiesAs.IsProduction = False
End If
I test the code using "WS006" and IsProduction will be equal to True. However, when I try to access the Get in clsProperties
IsProduction is equal to False.
If IsProduction Then
Debug.Print "Prod"
Else
Debug.Print "Dev"
End If
Please help!
You've set up your clsProperties module correctly. But there are some problems with the rest of the code as published (as it is, it won't compile, so you haven't cut and pasted actual code). Here's a stab at a fix:
Private objProperties As New clsProperties
objPropertiesAs.IsProduction = (Environ("computername") = "WS0006")
Debug.Print Iif (objProperties.IsProduction, "Prod", "Dev")
I've done some things to make your code more concise. The only substantive difference between my code and yours is that yours doesn't reference the object with which your IsProduction property is associated when you do the Get. I don't know why you aren't getting an "Object Required" error there, but perhaps you have an On Error Resume Next in your code somewhere.

Outlook VBScript Expected Statement Error

I'm new to this site. I have searched thoroughly for an answer and cannot seem to locate an answer. I hope one of you fine people will be able to help me....
Thank you
When I try to run my custom form with code show below, I get the following message:
Script Error
Expected statement
Line No:33
Code:
Function Item_Open()
Dim LeaveItem
Dim IO
If not Connection_Open Then
MsgBox("Error connecting to SI")
LeaveItem = True
Item_Open = False
Else
Item_Open = False
End If
End Function
Function Item_Close()
If LeaveItem = True Then
Exit_Function
Else
End If
End Function
Subroutine Connection_Open()
Dim oSI
Set oSI = New ADODB.Connection
Dim ostrSI
oSI.ConnectionString = "Driver={Progress OpenEdge 10.1C Driver};HOST=192.168.1.1;DB=kob;UID=sii;PWD=sisys1;PORT=2501;"
oSI.Open
End Sub
Change
Subroutine Connection_Open()
to
Sub Connection_Open()

Setting a VCProject property to default

I'm trying some VS2005 IDE macros to modify a large amount of projects (~80) within a solution. Some of the properties I wish to set do expose a programmatic interface to 'default', but many others do not. Is there a generic way to set such properties to their default? (eventually meaning erasing them from the .vcproj file)
Simplified example, setting some random properties:
Sub SetSomeProps()
Dim prj As VCProject
Dim cfg As VCConfiguration
Dim toolCompiler As VCCLCompilerTool
Dim toolLinker As VCLinkerTool
Dim EnvPrj As EnvDTE.Project
For Each EnvPrj In DTE.Solution.Projects
prj = EnvPrj.Object
cfg = prj.Configurations.Item(1)
toolLinker = cfg.Tools("VCLinkerTool")
If toolLinker IsNot Nothing Then
' Some tool props that expose a *default* interface'
toolLinker.EnableCOMDATFolding = optFoldingType.optFoldingDefault
toolLinker.OptimizeReferences = optRefType.optReferencesDefault
toolLinker.OptimizeForWindows98 = optWin98Type.optWin98Default
End If
toolCompiler = cfg.Tools("VCCLCompilerTool")
If toolCompiler IsNot Nothing Then
' How to set it to default? (*erase* the property from the .vcproj)'
toolCompiler.CallingConvention = callingConventionOption.callConventionCDecl
toolCompiler.WholeProgramOptimization = False
toolCompiler.Detect64BitPortabilityProblems = False
End If
Next
End Sub
Any advice would be appreciated.
For VS 2005, I believe you can use the ClearToolProperty method on VCConfiguration. The following code would accomplish this for CallingConvention (this is C#, but I'm sure something similar works for VB):
cfg.ClearToolProperty( toolCompiler, "CallingConvention" );
This would have the same effect as going into the GUI and choosing "<inherit from parent or project defaults>" for this option.
Unfortunately this seems to be deprecated in VS 2010, and I'm not sure what the new supported method is.

How do I get visual studio to not wait on temporarily blocked tests?

I'm relatively new to unit testing, and trying it on my personal projects. I want to unit test some concurrent methods (futures which run actions in the thread pool). To avoid the test method finishing before the thread pooled action, I'm blocking the test. Here is the actual blocking code:
Private Shared Function BlockOnFuture(ByVal future As IFuture,
ByVal timeout As TimeSpan) As Boolean
Dim waitHandle = New System.Threading.ManualResetEvent(initialState:=False)
AddHandler future.Ready, Sub() waitHandle.Set()
If future.State <> FutureState.Unknown Then waitHandle.Set() 'already ready'
Return waitHandle.WaitOne(timeout)
End Function
Private Shared Function BlockOnFuture(ByVal future As IFuture) As Boolean
Return BlockOnFuture(future, New TimeSpan(0, 0, seconds:=5))
End Function
I have tests which intentionally don't set a future, for example:
<TestMethod()>
Public Sub CallWhenReady_Dangle()
Dim flag = True
Dim future = New FutureAction() 'A class which has methods to make it become ready'
Dim result = future.CallWhenReady(Sub(exception)
flag = False
End Sub)
'should fail, because the future action is not being set'
Assert.IsFalse(BlockOnFuture(result))
'future was not set so the action did not run'
Assert.IsTrue(flag)
'action did not run so the result should not be set either'
Assert.IsTrue(result.State = FutureState.Unknown)
End Sub
I think Visual studio runs the tests one by one, because every test waits patiently while this one takes 5 seconds to timeout and complete. Is there a way I can force certain tests to run concurrently? Am I approaching this wrong?
It's been a long day but I think my advice would be the approach is wrong. Really you want to stub out the future behavior.
A kluge would be to modify the default test timeout. You can do this with an attribute I think (most test Fx let you do this but I can't remember the syntax for MSTest which appears to b the one you're using).

Resources