Results 1 to 4 of 4

Thread: [RESOLVED] How to unit test this method?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    May 2002
    Posts
    1,602

    Resolved [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

  2. #2
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    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:
    1. Public Class DialogService
    2.     Public Async Function ShowYesNoAsync(message As String, title As String, icon As MessageBoxImage) As Task(Of Boolean) Implements IDialogService.ShowYesNoAsync
    3.         Return Await Task.Run(Function()
    4.                                   Dim res = GetMessageBoxResult(message, title, icon)
    5.  
    6.                                   If (res = MessageBoxResult.Yes) Then
    7.                                       Return True
    8.                                   Else
    9.                                       Return False
    10.                                   End If
    11.                               End Function)
    12.     End Function
    13.  
    14.     Protected Overridable Function GetMessageBoxResult(message As String, title As String, icon As MessageBoxImage) As MessageBoxResult
    15.         Return MessageBox.Show(message, title, MessageBoxButton.YesNo, icon)
    16.     End Function
    17. End Class
    18.  
    19. Public Class TestableDialogService
    20.     Inherits DialogService
    21.  
    22.     Private _userInput As MessageBoxResult
    23.  
    24.     Public Sub New(userInput As MessageBoxResult)
    25.         _userInput = userInput
    26.     End Sub
    27.  
    28.     Public Overrides Function GetMessageBoxResult(message As String, title As String, icon As MessageBoxImage) As MessageBoxResult
    29.         Return _userInput
    30.     End Function
    31. 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]

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    May 2002
    Posts
    1,602

    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

  4. #4
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    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
  •  



Click Here to Expand Forum to Full Width