chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hello,
I saw a previous post asking about public members and the reply suggested refactoring code to use a getter. I also saw the sample in the docs but that was a public field with an object and calling a method on that object.

I am testing against a vendor's code base and cannot refactor nor get them to change things so I can test. These are value type public members. And these public members will take us down different branches of the code so I can test these paths.

This is a ASP.NET webservice and the object MemberObject is a descendant of "large" chain of objects, and I wanted the power of Members.ReturnRecursiveFakes because of the 10s and 10s of dependencies, like HttpContext assessors, items checking web/app config files, etc.

Here is my example, question...
//mock the webservice
MemberWebService fakeService = Isolate.Fake.Instance<MemberWebService>(Members.ReturnRecursiveFakes);
//Call the original webMethod we want to test
Isolate.WhenCalled(()=> fakeService.CreateRoleCollection(1,1,true)).CallOriginal();

//This MemberObject is created first in the method CreateRoleCollection
MemberObject fakeMember = Isolate.Fake.Instance<MemberObject>(Members.ReturnRecursiveFakes);
Isolate.Swap.NextInstance<MemberObject>().With(fakeMember);
//[1] attempted stuff here, read below

//Now based on public fields it takes different branches.
//For example, it has a public Int32 roleID, say 222 = admin, 333 = regular user.
//and yea, I think it should be a get but I can't change their code.
//in code there is something like this.

if(roleID == 222){..} else if (roleID ==333){...};

How can I set the int32 property of the public field on memberobject?

I tried directly setting it at the [1] marker.
I tried the following also at the [1] marker.
MockObject theMock = MockManager.GetMockOf(fakeMember);
theMock.AssignField("RoleID", (Int32)222);

//If I debug, the value is not my 222 or whatever other field I'm try doesn't take the value.

//Proceed to call fakeService and isolate verify stuff below.


Can someone help me on this? Sorry if this question seems so obvious to everyone.

Thanks,
GohperCoder
asked by GopherCoder (1.7k points)

3 Answers

0 votes
I think the problem you're having is that you're mixing APIs - you shouldn't try to use both Arrange/Act/Assert and Reflective/Natural mocks in the same test. They're really not meant to go together and it doesn't work out well.

To the best of my knowledge, right now the AAA stuff doesn't support field mocking - it's coming.

In the meantime, here's how you'd do it in Reflective/Natural mocks. Note that I cobbled together a minimal reproduction to illustrate the point - obviously your stuff is more complex than this. If it turns out this sort of solution doesn't work for you, you may need to post a little more in the way of example code to show us how we might be able to better help you.

public class MemberObject
{
  private int roleID;
  
  public MemberObject(int role)
  {
    this.roleID = role;
  }
  
  public int DoSomethingRoleSpecific()
  {
    // This is where the private field is used.
    if(this.roleID >0)
    {
      return 1;
    }
    else if(this.roleID == 0)
    {
      return 0;
    }
    return -1;
  }
}

public class MemberWebService
{
  public MemberObject CreatedMember { get; private set; }
  public void CreateRoleCollection(int role, int b, bool c)
  {
    this.CreatedMember = new MemberObject(role);
  }
}

[TestFixture]
[VerifyMocks]
public class MyTestFixture
{
  [Test]
  public void ReflectiveAndNatural()
  {
    // The next instance of a MemberObject that gets created will have
    // its roleID set to -1.
    Mock<MemberObject> mockMemberObject = MockManager.Mock<MemberObject>();
    mockMemberObject.AssignField("roleID", -1);
    
    // Set up expectations against an actual MemberWebService.
    MemberWebService fakeService = new MemberWebService();
    using(RecordExpectations recorder = RecorderManager.StartRecording())
    {
      fakeService.CreateRoleCollection(1, 1, true);
      recorder.CheckArguments();
      recorder.CallOriginal();
    }
    
    // This would normally make the member object have an internal role ID of 1,
    // which means the role-specific method will return 1. Our fake will
    // cause the role-specific method to return -1.
    fakeService.CreateRoleCollection(1, 1, true);
    Assert.AreEqual(-1, fakeService.CreatedMember.DoSomethingRoleSpecific());
  }
}
answered by tillig (6.7k points)
0 votes
Thanks for your reply Travis, I will try to test it out today. But here are my thoughts, and anyone please correct me if I am wrong.

I wanted the use AAA syntax because of RecursiveMocking, this webservice and objects within are so tightly bound to System.Web items, some are public fields, some properties, that I get all sorts of errors like, and this is off the top of my head, but "cannot create this outside asp.net context" when I tried to create objects. And as I thought Natural / Reflective can't do recursive mocking...which is why I avoid those two frameworks with this particular set of legacy code.

I couldn't find the field mocking section of the AAA so I remember reading the part about combining the other two to do things, so I tried it with AAA. And I remember the section about assignField, so I went ahead and tried to make my Typemock salad.

Following is just my misconception but hopefully it illustrates my flawed way of thinking... :oops:

the documents portrayed the various API's as evolutions of features. Started with reflective, moved to natural, moved to AAA. And the documents have a section about combining reflective and natural, and things like the cheat sheets don't have AAA syntax, and other similar things.

So..(with a long drawn-out 'o' sound and a smattering of uncertainty)...I thought that the documents were just not up-to-date and that mixing frameworks of any of the three was ok and that one day there would be docs on it. NOTE: I am aware that this was my assumption and it is most likely wrong, hence probably why I am having so much trouble.

As I understand it now and will try....
AAA doesn't have field level mocking/stubbing. Can't do, use reflective/natural.
Natural/Reflective can't do recursive mocks, have to mock all field level objects by hand.
Safe Mix Natural/Reflective
Don't Mix AAA with the others - Lots of fizzing and bubbling.


Thanks again Travis
GopherCoder
answered by GopherCoder (1.7k points)
0 votes
You're right - The documentation should be more explicit on this subject.
We will update Isolator document to include a clarification.

I'd like to mention the fact that we're adding new functionality to the AAA API so hopefully in the neat future you won't need to use Natural/Refelctive mocks.
answered by dhelper (11.9k points)
...