Mocking Method with out-param

4 posts, 1 answers
  1. Christian
    Christian avatar
    5 posts
    Member since:
    Apr 2013

    Posted 25 Jul 2013 Link to this post


    class and method
    public class A
    {
      public static bool TryGet<T>(string key, out T obj)
      {
          ....
      }
    }
     
    usage
    public static object AMethod(string key)
    {
    object values;
     
    if (A.TryGet(key, out values))
    {
      return values;
    }
     
    return null;
    }

    now i want to write a test for method AMethod and mock A.TryGet. How can I do that? I tried different approaches, but wasnt able to create a mock of the TryGet extension. I want to set the "obj" variable in the "TryGet" method do different values depending on the passed key (using "Returns" or "DoInstead")


  2. Answer
    Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 25 Jul 2013 Link to this post

    Hello Christian,

    Thank you for contacting our forums.

    I wrote the following test method and it behaves as expected:
    [TestMethod]
    public void AMethod_OnExecuteWithAnyStringAndArrangedPositiveBool_ShouldReturnAsExpected()
    {
        object expected = "test";
     
        // Arrange - When A.TryGet<object>() is called with any string argument,
        //  it should return true and pass the value of "expected" to the out argument.
        Mock.Arrange(() => A.TryGet<object>(Arg.AnyString, out expected)).Returns(true);
     
        // Act
        object actualOutArg = string.Empty;
        var actual = AMethod("any string here");
     
        // Assert
        Assert.AreEqual(expected, actual);
    }
    The only thing you should be careful with is matching the constraints and the arguments in the arrangement.

    For example, if you have another method (similar to the AMethod, but a string function), like this:
    public static string StringMethod(string key)
    {
        string values;
     
        if (A.TryGet(key, out values))
        {
            return values;
        }
     
        return null;
    }
    You will need to pass out string as an argument in the arrangement and also arrange for  A.TryGet<string>() as follows:
    string expectedString = "test1";
     
    // Arrange - When A.TryGet<string>() is called with any string argument,
    //  it should return true and pass tha value of "expected" to the out argument.
    Mock.Arrange(() => A.TryGet<string>(Arg.AnyString, out expectedString)).Returns(true);
     
    // Act
    object actualOutArg = string.Empty;
    var actual = StringMethod("any string here");
     
    // Assert
    Assert.AreEqual(expectedString, actual);

    I hope this helps. Please, let me know if there is anything else I can assist you with.

    Regards,
    Kaloyan
    Telerik
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
  3. DevCraft R3 2016 release webinar banner
  4. Christian
    Christian avatar
    5 posts
    Member since:
    Apr 2013

    Posted 25 Jul 2013 Link to this post

    thank you. I think that would work in my case. However how would you set up the mock if you have something like:

    public static object AMethod(string key)
    {
    Hashtable values = new Hashtable();
      
    if (A.TryGet(key, out values))
    {
     values.Add("A", "abc");
    }
      
    return values;
    }

    Now i want to write a test for method "AMethod" that tests if the returned Hashtable contains the value "abc"?

    [TestMethod]
    public void AMethod_OnExecuteWithAnyStringAndArrangedPositiveBool_ShouldReturnAsExpected()
    {
        Hashtableexpected = new Hashtable();
      expected.Add("A", "abc");
     
        // setup mock here
        //?? Mock.Arrange(() => A.TryGet<object>(Arg.AnyString, out expected)).Returns(true);
     
        // Act
        Hashtable actual = AMethod("any string here");
     
        // Assert
        Assert.AreEqual(expected, actual);
    }

  5. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 25 Jul 2013 Link to this post

    Hi again Christian,

    I am glad my previous answer helped you.

    About your next question, I made this example:
    // You will pass this Hashtable as an out-param in the arrangement.
    // Then you will assert against it, as it should be populated according to the method being tested.
    Hashtable actual = new Hashtable();
     
    // Arrange - This time we use Hashtable as a constraint.
    Mock.Arrange(() => A.TryGet<Hashtable>(Arg.AnyString, out actual)).Returns(true);
     
    // Act
    AMethod("any string here");
     
    // Assert - We assert against our expectations.
    Assert.AreEqual(1, actual.Count);
    Assert.IsTrue(actual.ContainsKey("A"));
    Assert.IsTrue(actual.ContainsValue("abc"));
    Note that, you don`t need to populate the Hashtable inside the test method. As the method under test (AMethod) is supposed to do this, we should only assert against our expectations.

    Let me know if this works for you.

    Regards,
    Kaloyan
    Telerik
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
Back to Top