|
-
Apr 22nd, 2015, 02:48 AM
#1
Thread Starter
Frenzied Member
[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
-
Apr 22nd, 2015, 05:50 AM
#2
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]
-
Apr 22nd, 2015, 12:09 PM
#3
Thread Starter
Frenzied Member
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
-
Apr 23rd, 2015, 06:23 AM
#4
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|