[RESOLVED] How to unit test this method?
Code:
Public Async Function ShowYesNoAsync(message As String, title As String, icon As MessageBoxImage) As Task(Of Boolean) Implements IDialogService.ShowYesNoAsync
Return Await Task.Run(Function()
Dim res = MessageBox.Show(message, title, MessageBoxButton.YesNo, icon)
If (res = MessageBoxResult.Yes) Then
Return True
Else
Return False
End If
End Function)
End Function
Hi
I want to unit test the above method to make sure that the if statement is tested, you never know, someone might flip the true/false and cause weirdness.
I am however not sure how to do it. I have an interface IDialogService where this method is present, but there is no way to "mock" the messagebox.show() method to simulate a Yes/No response? Would it be possible with some refactoring of the method to somehow inject a fake dialogresult, since that is really all I need because that is what the if statement reacts on...
thanks
Henrik
Re: How to unit test this method?
Given that this is an implementation of an interface that abstracts away the notion of a message box, then my first thought of Humble Dialog is irrelevant.
So I'd suggest in this case, it's probably not too horrible to do the following:
vbnet Code:
Public Class DialogService
Public Async Function ShowYesNoAsync(message As String, title As String, icon As MessageBoxImage) As Task(Of Boolean) Implements IDialogService.ShowYesNoAsync
Return Await Task.Run(Function()
Dim res = GetMessageBoxResult(message, title, icon)
If (res = MessageBoxResult.Yes) Then
Return True
Else
Return False
End If
End Function)
End Function
Protected Overridable Function GetMessageBoxResult(message As String, title As String, icon As MessageBoxImage) As MessageBoxResult
Return MessageBox.Show(message, title, MessageBoxButton.YesNo, icon)
End Function
End Class
Public Class TestableDialogService
Inherits DialogService
Private _userInput As MessageBoxResult
Public Sub New(userInput As MessageBoxResult)
_userInput = userInput
End Sub
Public Overrides Function GetMessageBoxResult(message As String, title As String, icon As MessageBoxImage) As MessageBoxResult
Return _userInput
End Function
End Class
Your unit tests need to instantiate a TestableDialogService to test. This isn't great practice in general, but in this limited scenario isn't unreasonable. Classes that depend on IDialogService would use a double of IDialogService rather than this class, of course. However, you might then go on to find that your use of Tasks is hampering in unit tests because you are creating them in the unit under test - I have found that problematic in unit tests because the threading model is different to your app's environment and you really don't want threading in your unit tests if you can help it.
[Edit: In case it's not clear, TestableDialogService should be defined with your unit tests]
Re: How to unit test this method?
Thanks for the reply. I did manage to do something similar but with Microsoft Fakes, where I used a shim of the System.Windows.MessageBox and just made teh show method return whatever I desired(dialogresult Yes or No).
This stuff is messy to test and maybe not worth the effort, since it is most unlikely that someone will ever break it (but we all heard that one before...)
cheers
Henrik
Re: [RESOLVED] How to unit test this method?
Yes, it's messy but it's the point where your abstractions hit the metal of the frameworks, so it is always going to be messy. The fact that you have the abstraction so that all your business logic can be tested in a non-messy way is key, and leaves you free to decide whether having this thin sliver of "glue" code tested is worth the small, localised mess.