locked
Unit Testing Background Tasks, WinMD, and Async methods

    Question

  • Is there any advice on writing unit test code for WinMD assemblies?  Most of my classes are internal, which makes them quite difficult to test from a different assembly.  

    I can add internalvisible to in the WinMD assembly, but I still run into issues.

    In my unit test, I am able to invoke my internal classes/methods, but if one of the async methods has a type of Task<Something> where something is internal, MS Test refuses to count it as a unit test for some reason.

    example:

    [TestMethod]
            public void ThisIsNotRecognizedAsATest()
            {
                GeneralThreadAffineContext.Run(async () =>
                                                         {
                                                             // Because InternalType is internal to another assembly, MSTESt does not reecognize this test
                                                             Task<InternalType> something = await _internalClass.GetSomethingAsync();
                                                             Assert.IsNotNull(something);
                                                         });
            }
    
            [TestMethod]
            public void ThisIsRecognizedAsATest()
            {
                GeneralThreadAffineContext.Run(async () =>
                {
                    // Because string is NOT internal to another assembly, MSTESt will reecognize this test
                    Task<string> something = await _internalClass.GetSomethingElseAsync();
                    Assert.IsNotNull(something);
                });
            }

    I have also experienced problems where class members that are not null become null immediately after the method exits.  For instance, sometimes if I have an Arrange() method where I initialize test dependencies, they become null once Arrange() completes and the actual test starts.

    I feel as if I am doing something completely wrong.

    1. How does MS recommend to test WinMD projects with internal classes?
    2. How does MS recommend to test Async methods?
    3. Does MS still recommend to use GeneralThreadAffineContext?

    Thanks,

    Wednesday, April 25, 2012 4:01 AM

Answers

  • Hi Jason,

    Thanks for using VS11 and giving your feedback.

    The issue of discovery while using a type from WinMD in context of async is a known issue and already fixed in our latest code base. Fix will be available in future builds of Visual Studio.

    To answer your queries:

    1. To test internal classes in WinMD
    Create a WinMD project and take reference of "MSTestFramework" sdk (Right click on project -> Add Reference ... -> Windows -> Extensions -> MSTest for managed projects).

    Add your internal class and a test class in WinMD project. After adding "MSTestFramework" you can use Assert library.

    internal class MyClass
    {
        public int MyMethod()
        {
            return 0;
    } } public sealed class TestClassForMyClass { public void TestMethodForMyMethod() { MyClass myClass = new MyClass(); int result = myClass.MyMethod(); Assert.AreEqual(0, result); } }

    Add "Unit Test Library" for "Windows Metro apps" and take reference of WinMD project. Write test method as follows to call your public TestClassForMyClass in Winmd.

    [TestClass]
    public class MyTestClass
    {
        private TestClassForMyClass actualTestClass = new TestClassForMyClass();
    
        [TestMethod]
        public void TestMethod1()
        {
            actualTestClass.TestMethodForMyMethod();
        }
    }

    2. In Consumer Preview there is a support for async test methods. You can test async methods using async-await as follows

    [TestMethod]
    public async Task TestMethod1()
    {
        var result = await SomeAsyncMethod();
        Assert.IsNotNull(result);
    }

    Note: While using async TestMethod return type must be "Task" else test will become false positive.


    Regards,
    Vikram Agrawal,
    Developer, VSTLM, Microsoft Corporation


    Thursday, May 3, 2012 6:34 PM

All replies

  • Jason - I'm moving this to the tools forum.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator

    Friday, April 27, 2012 5:43 PM
    Moderator
  • Hi Jason,

    Thanks for using VS11 and giving your feedback.

    The issue of discovery while using a type from WinMD in context of async is a known issue and already fixed in our latest code base. Fix will be available in future builds of Visual Studio.

    To answer your queries:

    1. To test internal classes in WinMD
    Create a WinMD project and take reference of "MSTestFramework" sdk (Right click on project -> Add Reference ... -> Windows -> Extensions -> MSTest for managed projects).

    Add your internal class and a test class in WinMD project. After adding "MSTestFramework" you can use Assert library.

    internal class MyClass
    {
        public int MyMethod()
        {
            return 0;
    } } public sealed class TestClassForMyClass { public void TestMethodForMyMethod() { MyClass myClass = new MyClass(); int result = myClass.MyMethod(); Assert.AreEqual(0, result); } }

    Add "Unit Test Library" for "Windows Metro apps" and take reference of WinMD project. Write test method as follows to call your public TestClassForMyClass in Winmd.

    [TestClass]
    public class MyTestClass
    {
        private TestClassForMyClass actualTestClass = new TestClassForMyClass();
    
        [TestMethod]
        public void TestMethod1()
        {
            actualTestClass.TestMethodForMyMethod();
        }
    }

    2. In Consumer Preview there is a support for async test methods. You can test async methods using async-await as follows

    [TestMethod]
    public async Task TestMethod1()
    {
        var result = await SomeAsyncMethod();
        Assert.IsNotNull(result);
    }

    Note: While using async TestMethod return type must be "Task" else test will become false positive.


    Regards,
    Vikram Agrawal,
    Developer, VSTLM, Microsoft Corporation


    Thursday, May 3, 2012 6:34 PM