I am using VS2010, writing unit tests with MSTest. My project uses WPF, MVVM and the PRISM framework. I am also using Moq to mock interfaces.
I am testing the interaction between a command and a selected item in a list. The interaction is encapsulated in a ViewModel according to the MVVM pattern. Basically, when the SelectedDatabase is set, I want the Command to raise CanExecute. I have written this test for the behaviour:
public void Test()
{
var databaseService = new Mock<IDatabaseService>();
var databaseFunctionsController = new Mock<IDatabaseFunctionsController>();
// Create the view model
OpenDatabaseViewModel viewModel
= new OpenDatabaseViewModel(databaseService.Object, databaseFunctionsController.Object);
// Mock up the database and its view model
var database = TestHelpers.HelpGetMockIDatabase();
var databaseViewModel = new DatabaseViewModel(database.Object);
// Hook up the can execute changed event
var resetEvent = new AutoResetEvent(false);
bool canExecuteChanged = false;
viewModel.OpenDatabaseCommand.CanExecuteChanged += (s, e) =>
{
resetEvent.Set();
canExecuteChanged = true;
};
// Set the selected database
viewModel.SelectedDatabase = databaseViewModel;
// Allow the event to happen
resetEvent.WaitOne(250);
// Check that it worked
Assert.IsTrue(canExecuteChanged,
"OpenDatabaseCommand.CanExecuteChanged should be raised when SelectedDatabase is set");
}
On the OpenDatabaseViewModel
, the SelectDatabase
property is as follows:
public DatabaseViewModel SelectedDatabase
{
get { return _selectedDatabase; }
set
{
_selectedDatabase = value;
RaisePropertyChanged("SelectedDatabase");
// Update the can execute flag based on the save
((DelegateCommand)OpenDatabaseCommand).RaiseCanExecuteChanged();
}
}
And also on the viewmodel:
bool OpenDatabaseCanExecute()
{
return _selectedDatabase != null;
}
TestHelpers.HelpGetMockIDatabase()
just gets a mock IDatabase
with some properties set.
This test passes when I run the test from VS2010, but fails when executed as part of an automated build on the server. I put in the AutoResetEvent
to try to fix the problem, but it's had no effect.
I discovered that the automated tests were using the noisolation
flag in the MSTest command line, so I removed that. However, that produced a 'pass' once, but a 'fail' the next.
I think I am missing something important in all of this, but I can't figure out what it is. Can anyone help by telling me what I'm doing wrong?