Skip to content

billsheh/thread-affiliated-method-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 

Repository files navigation

This utility function allows you to test a method requiring running within one thread. For example, for a method in a view model, it is better tested simulating the runtime enviroment, i.e., the method will be executed in UI thread.

The basic usage is rather simple, to test the following method, excepted from Stephen Toub's blog, http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx

    static async Task PrintThreadInfo()
    {
        //
        var d = new Dictionary<int, int>();
        for (int i = 0; i < 10000; i++)
        {
            int id = Thread.CurrentThread.ManagedThreadId;
            int count;
            d[id] = d.TryGetValue(id, out count) ? count + 1 : 1;

            await Task.Yield();
        }
        foreach (var pair in d) Console.WriteLine(pair);
    }
    
    [Test]
    public async void PrintThreadInfo_ThreadPool_Test()
    {
        await Task.Run(async () =>
        {
            await PrintThreadInfo();
        });
    }

The method above will output one line in a thread affiliated enviroment but it will output multiple lines in a thread pool enviroment.

    [Test]
    public void PrintThreadInfo_Test()
    {
        Console.WriteLine("Testing thread Id {0}", Thread.CurrentThread.ManagedThreadId);

        TestingUtility.RunThreadAffiliatedMethod(() => PrintThreadInfo());
    }

It can also work with exception test, shown below:

    [Test]
    [ExpectedException("System.Exception", ExpectedMessage = "Test exception")]
    public void Exception_Test()
    {
        TestingUtility.RunThreadAffiliatedMethod(async () => { throw new Exception("Test exception"); });
    }

What it means to testing

This simple utility can be used to test all UI such as a dialog, View Models, etc which must be running in a dedicated thread. You will find the testing quite complex if you refers to the PRISM reference implementations. With this utility you can write testing code like this:

    [TestMethod]
    public void OpenFolderDialog_Test()
    {
        TestingUtility.RunThreadAffiliatedMethod(async () =>
        {
            var dialog = new CommonOpenFileDialog();
            dialog.IsFolderPicker = true;
            dialog.Title = "Test dialog";
            CommonFileDialogResult result = dialog.ShowDialog();
            if (result != CommonFileDialogResult.Ok)
                return;
            else
                Trace.WriteLine(dialog.FileName);
        });
    }

Internals

There are other ways to write such kind of testing utility, like using thread affiliated scheduler[1] or DispatcherSynchronizationContext[2], but those are not easy to understand. Here I am following the very basic approach: create a message pump(i.e., Dispatcher) and pump message(method to be tested) into the message loop. Once the method is executed, exit the message loop(Dispatcher). Turn on the second debug flag, you will see some useful thread exectuing information.

    [1] Stephen Toub - http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx 
    [2] Custom Scheduler - http://www.journeyofcode.com/custom-taskscheduler-sta-threads/

About

Testing utility to test async methods affiliated with a single thread, like methods in a view model

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages