Determine if a method by name has been called.

4 posts, 0 answers
  1. Marcos
    Marcos avatar
    2 posts
    Member since:
    Aug 2011

    Posted 24 Aug 2011 Link to this post

    I am trying to determine if a method exists and then test if that method has been called. The only interface that is available to the test project in the below example code is I1.

    public interface I1 { }
    public interface I2 : I1
    {
        void Test();
    }
    My test code looks like this
    [TestMethod()]
    public void MyClassConstructorTest()
    {
        this.Test<I2>();
    }
     
    public void Test<T>() where T : I1
    {
        T t = Mock.Create<T>();
        bool called = false;
        Mock.NonPublic.Arrange(t, "Test").DoInstead(() => called = true);
    }

    This throws this error: "Could not resolve the target method; make sure that you have provided arguments correctly.". I have put this code into the function to make sure that Mock.Create creates the appropriate proxy.
    MethodInfo method = t.GetType().GetMethod("Test");
    MethodInfo is never null so that tells me that a valid proxy has been created.

    My question is: Am I going about this the wrong way? How can I tell if a method that the test only knows by name and not by interface has actually been called?

    Thank you for your help.
  2. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 26 Aug 2011 Link to this post

    Hi Marcos,

    Thanks again for reporting the issue. However you don't need to do non-public mocking since the member you are trying to mock is from an interface and accessible.

    Here you can write it in the following way:

    public void Test<T>() where T : I2
    {
        T t = Mock.Create<T>();
        
        bool called = false;
     
        Mock.Arrange(() => t.Test()).DoInstead(() => called = true);
     
        Assert.IsTrue(called);
    }

    The changes here are :
    1. I have used where T : I2 instead of I1 since the methodTest() is actually in I2 not in I1 and by definition you can cast I2 to I1 and use members from I1 but cannot cast to parent class and use a member from child. In that regard the exception remains valid since it’s not private and Test() do not belong to I1.
    2. I have used Mock.Arrange instead of Mock.NonPublic.Arrange  since it’s not private or protected.

    Hope this solves your issue.


    Kind Regards,
    Mehfuz
    the Telerik team

    Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

  3. DevCraft R3 2016 release webinar banner
  4. Marcos
    Marcos avatar
    2 posts
    Member since:
    Aug 2011

    Posted 26 Aug 2011 Link to this post

    That will not work as I had mentioned that only I1 is available to the test framework. I2 resides in another assembly that the test framework can not reference. Because of this very fact is the entire reason I have this particular problem.

    Thanks for looking into this though.
  5. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 30 Aug 2011 Link to this post

    Hi Marcos,

    Thanks for the reply.  In this regard, if you can pass the class that implements the I2 interface then you will be able to mock it from another assembly.

    Here is the example:

    [TestMethod()]
    public void MyClassConstructorTest()
    {
        this.Test(new I2Class());
    }
     
    public class I2Class : I2
    {
        public void Test()
        {
            throw new NotImplementedException();
        }
    }
     
    public void Test(I1 instance)
    {
        bool called = false;
     
        Mock.NonPublic.Arrange(instance, "Test").DoInstead(() => called = true);
     
        I2 i2 = instance as I2;
     
        i2.Test();
     
        Assert.IsTrue(called);
    }

    However In your previous example, you are just passing the type from which Mock.Create is creating a dynamic instance and i found in this particular case it fails to resolve the method from I2 instance (shown in your first post). Therefore i made fix to that and if you need the latest internal build please send us a support ticket and we will attach one (since we can’t send it in public forum).


    Kind Regards,
    Mehfuz.
    the Telerik team

    Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

Back to Top