Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically generate keydown presses for WPF unit tests

I am trying to unit test a WPF control and need to simulate key down presses. I have seen a possible solution here, however when I try to pass in a PresentationSource I keep getting a null value (from either PresentationSource.FromVisual() or PresentationSource.FromDependencyObject()) which triggers an exception.

My question is how do I get a non-null PresentationSource that I can use in unit tests?

like image 411
jonathan_ou Avatar asked Dec 27 '10 09:12

jonathan_ou


3 Answers

You can extend the PresentationSource class like this:

public class FakePresentationSource : PresentationSource
{
    protected override CompositionTarget GetCompositionTargetCore()
    {
        return null;
    }

    public override Visual RootVisual { get; set; }

    public override bool IsDisposed { get { return false; } }
}

And use it like this:

var uiElement = new UIElement();

uiElement.RaiseEvent(new KeyEventArgs(Keyboard.PrimaryDevice, new FakePresentationSource(), 0, Key.Delete) 
{ 
    RoutedEvent = UIElement.KeyDownEvent 
});
like image 61
acochran Avatar answered Oct 28 '22 06:10

acochran


A quicker solution for unit tests is just to mock the PresentationSource object. Note that it requires an STA thread. Sample uses Moq and nunit.

[Test]
[RequiresSTA]
public void test_something()
{
  new KeyEventArgs(
    Keyboard.PrimaryDevice,
    new Mock<PresentationSource>().Object,
    0,
    Key.Back);
}
like image 9
Bill Tarbell Avatar answered Oct 28 '22 07:10

Bill Tarbell


Figured this out after reading this post.

Basically, you need to put your control inside a Window and call Window.Show() on it. The post mentioned an WPF bug, but I didn't encounter this in WPF 4.

After calling Window.Show(), the presentation source will no longer be null and you will be able to send keys to the control.

like image 3
jonathan_ou Avatar answered Oct 28 '22 07:10

jonathan_ou