Daniel Sims Daniel Sims - 29 days ago 9
C# Question

Moq with c# System.Windows.MessageBoxButton.YesNoCancel

I'm currently writing some unit tests around a WPF module of a program. I've come to a point where a

ShowMessage
returns a
Yes
or
No
value within the statement.

dService.ShowMessage(view, args);


The args takes a lambda as (shortened)

new MessageArgs(arg1, arg2, arg3, (la) =>
{
if (la.result == messResult.yes)
{
// do something
}
}


I'm now trying to mock the result given back from this lambda but am having some difficulty and have been unable to find someone with a similar problem.

I've tried setting a default result within the lambda in my unit test:

new MessageArgs(arg1, arg2, arg3, (la) =>
{
if (la.result == messResult.yes)
{
la.result = messResult.yes;
}
}


Which proved unsuccessful along with trying to set the arg result below the statement as:

args.result = messResult.yes;


I have also tried to use Setup as:

dServiceMock.Setup(x => x.ShowMessage)


but there is no return property as
ShowMessage
is a void function.

None have shown a change in action from my unit test. Has anyone else had a similar "problem" and found a solution or know of some documentation around this? I'll update this if I find something in the mean time.

Thank you.

Answer

If dService is not an instance of a sealed class, create a subclass which overrides that ShowMessage method in a way you need for your test purposes.

Edit:

The problem arises by the dService.ShowMessage(view, args) call encapsulating two (or more) actions:
- calls view.ShowMessage
- calls the lambda enclosed in args with the result of view.ShowMessage

Now you have to create your dService.ShowMessage(view, args) such that:
- it does not show the view
- it assumes an outcome of that action instead
- calls the lambda with the desired outcome