0

In my WPF app, I have a MainWindow.xaml and a related MainWindow.xaml.cs. The latter has a property DatabaseAccessor which accesses a database:

public partial class MainWindow : System.Windows.Window
{
    public IDatabaseAccessor DatabaseAccessor { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        DatabaseAccessor = new RealDatabaseAccessor();
    }

    // [...]
}

Now I'm writing a test using FlaUI. In my test I'm writing something like

using FlaUI.UIA3;
using Moq;

var app = FlaUI.Core.Application.Launch("myapp.exe");
using (var automation = new UIA3Automation())
{
    FlaUI.Core.AutomationElements.Window window = app.GetMainWindow(automation);

    //// I am looking for a way to do something like this (but no such API exists):
    // MainWindow myWindow = (MainWindow) window.RealWindow;
    // myWindow.DatabaseAccessor = new Mock<IDatabaseAccessor>().Object;
}

For my tests, I do not want to communicate with the real database but mock it, instead.

How can I inject a mocked DatabaseAccessor into the Window opened with FlatUI (see the commented code in my last snippet)? Or in other words: How can I access the System.Windows.Window for a given FlaUI.Core.AutomationElements.Window?

If this is not possible, how would you approach such a problem?

Marteng
  • 1,179
  • 13
  • 31
  • Ideally you want to explicitly inject the dependency into the target class either via constructor or property injection. Depending on weather the platform or your design will allow that you may need to defer to the Locator anti-pattern. – Nkosi Apr 20 '22 at 11:21
  • 2
    @Marteng: You need to rethink what you are doing here. An UI *automation* test is not supposed to mock dependencies. It starts your app in a separate process and interacts with it using the actual elements that are presented on the screen. If you want to test a specific component in your code, you should write a *unit* test against this component. You can then mock any external dependencies. – mm8 Apr 20 '22 at 15:44
  • @mm8 you are probably right. We are writing actual unit tests where we mock external dependencies. However, we also want to write "unit tests for the UI". But yea, as you said, we probably have to rethink this. Thanks for your thoughts! – Marteng Apr 21 '22 at 06:56
  • @Marteng: I wrote an answer. Please accept it to close the thread if your original question has been answered. Thanks in advance. – mm8 Apr 21 '22 at 13:49
  • @mm8 I upvoted your answer. However, there must be a way to test an application's UI and mock e.g. the database behind it. I want to keep this question unanswered so that more people keep looking into it. – Marteng Apr 21 '22 at 15:40
  • Then you need to "mock" the database *before* you start the application in a separate process, i.e. you need to run some kind of test version of the app. This requires implementation. The UI automation tests don't perform any mocking. – mm8 Apr 22 '22 at 12:33
  • @mm8 I think about creating a "test app" which re-uses the main window of my real application. E.g. in the test project, I create a "App.xaml" which references the "MainWindow.xaml" of the project to test. I then could create mocks in my "Test App.xaml" and pass them to the MainWindow. This way I am not testing exactly the app that will be shipped, but something real close to it. Something like that: https://stackoverflow.com/a/10166597/5207900. However, I am currently lacking time to further try out that approach. Give me a few days. – Marteng Apr 22 '22 at 12:56
  • Yes, as mentioned, you need to set up some kind of test version of the app. From the test automation framework's point of view, it's just any app. – mm8 Apr 22 '22 at 13:02

1 Answers1

1

You need to rethink what you are doing here.

An UI automation test is not supposed to mock dependencies. It starts your app in a separate process and interacts with it using the actual elements that are presented on the screen.

If you want to test a specific component in your code, you should write a unit test against this component. You can then mock any external dependencies.

mm8
  • 163,881
  • 10
  • 57
  • 88