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
0 votes
Hello again everyone,

I apologize for all the posts, I'm burning precious time here just fumbling around and my performance is taking a hit. I feel like I might soon take the title of most inept TypeMock user soon.

Here is what I'm trying to do...
LegacyObject fakeObj = Isolate.Fake.Instance<LegacyObject>(Members.ReturnRecursiveFakes);

Isolate.WhenCalled(() => LegacyObject.Search("sqlString")).WillReturn(true);

//Now in the Save method there are a bunch of calls like the following..

obj.VerifyRules();
obj.Search("sqlString");
obj.Save();


When I call Isolate.Verify.WasCalledWithAnyArguments(()=>obj.Search("sqlString"));
it says the error about "was expected but was not called." However I can debug and watch it be called and return the value because it enters a branch below based on the boolean value. I can even hit that method in the Immediate window and it works with what I tell it to return.

The Verify checks on VerifyRules and Save work fine,
so I tried a sample and changed to obj.Search(); no params and Isolate.Verify it works fine.

Can someone point me in the right direction? I feel so stupid working with this, things just aren't working as well as I expected and I'm feeling like I should tuck my tail between my legs and just tell management I'm no good at this.

Thanks,
GohperCoder
asked by GopherCoder (1.7k points)

5 Answers

0 votes
I have a question about your example:

The second line (Isolate.WhenCalled...) shows you're setting up expectations around a static method call, but later on it appears you're calling an instance method. Is that correct?

I think there may be some detail being elided in the "// Now in the Save method..." comment that we might need to better assist you. Can you post a simple, but more complete reproduction of the issue?
answered by tillig (6.7k points)
0 votes
Hi,

I second Travis.
Most likely theres a confusion of instances in your test. :evil:
Meaning that you verify the calls on one instance while the actual calls are made on a different instance.

Mocking static stuff can get a little tricky on those parts, so if you can post a more complete test it will be nice. If not you may want to try using the tracer gui in order to make some order to the test
(:!: warning - I'm not sure if the tracer will make any sense when using the new AAA syntax)
answered by error (6.6k points)
0 votes
Sorry about that, it always sounds clear when writing it out.

Hopefully this is more clear.
A WebService has a webmethod DoSomeWork, which creates a single LegacyObject. This Legacy object has methods, none are static and non void.
bool VerifyRules()
bool Search("sqlString");
bool obj.Save();

So basically the web method looks something like this, just trying to illustrate that these methods are all in the mocked LegacyObject itself. Things like the VerifyRules, has to be mocked because it has a .config file that acts like a DI framework to load rule assemblies. Search loads up .config files for sql conn strings and so forth..its all pretty nasty.

So at the highest level...if VerifyRules failes..the system should not save. That is the sort of behavior testing I am trying to capture.

[WebMethod(true)]
public bool DoSomeWork(){
  if (obj.VerifyRules()){ 
      if(obj.Search("sqlString"){
          return obj.Save(); 
      }
   }else{return false;}
}


LegacyObject is part of a huge hierarchy with many instance members of items like HttpContext and mutators for HttpSession, Database methods..all rolled into one. I can't call original without mocking a huge number so I wanted AAA syntax to RecursivlyMock items.

My test was setup like the following.

LegacyObject fakeObj = Isolate.Fake.Instance<LegacyObject>(Members.ReturnRecursiveFakes); 
Isolate.WhenCalled(() => LegacyObject.VerifyRules).WillReturn(true);
Isolate.WhenCalled(() => LegacyObject.Save).WillReturn(true);
Isolate.WhenCalled(() => LegacyObject.Search("sqlString")).WillReturn(true);

//Did the isolate.swap next instance

//Called real code
CustWebService custWebService = new CustWebService();
//Call the actual method.
custWebService.DoSomeWork();

\These work fine, I can even say WasNotCalled to make this fail and play around
Isolate.Verify.WasCalledWithAnyArguments(()=>fakeObj.VerifyRules());
Isolate.Verify.WasCalledWithAnyArguments(()=>fakeObj.Save());

\no matter what I try here, this line causes a failure
Isolate.Verify.WasCalledWithAnyArguments(()=>fakeObj.Search("sqlString"));


Mind you, when I can get this to work. I will be setting expectations to return false and do a verify.wasNotCalled for an additional test and true to make sure it is saving.

I guess my issue is that I have mocked LegacyObject, and everything in it should be mocked, and when I call verify on any method on that object that I have set up expectations for: if they are parameterless, they work. If it has parameters, it gives me the error.

I hope that makes things more clear, and thanks for your time and effort.
answered by GopherCoder (1.7k points)
0 votes
Unfortunately, I'm guessing that the reason this is failing is something is happening inside the stuff you're not able to share here. I put the following reproduction together based on what you said above:

public class CustWebService
{
  private LegacyObject obj = new LegacyObject();
  
  public bool DoSomeWork(){ 
    if (obj.VerifyRules()){ 
      if(obj.Search("sqlString")){ 
        return obj.Save(); 
      } 
    }
    return false;
  }
}

// Every method on the LegacyObject throws an exception
// so we can quickly see if the mocking isn't set up right.
public class LegacyObject
{
  public bool VerifyRules()
  {
    throw new NotImplementedException();
  }
  
  public bool Search(string query)
  {
    throw new NotImplementedException();
  }
  
  public bool Save()
  {
    throw new NotImplementedException();
  }
}

[TestFixture]
public class MyTestFixture
{
  [Test]
  public void MyTest()
  {
    // Set up the mocks
    LegacyObject fakeObj = Isolate.Fake.Instance<LegacyObject>(Members.ReturnRecursiveFakes); 
    Isolate.WhenCalled(() => fakeObj.VerifyRules()).WillReturn(true); 
    Isolate.WhenCalled(() => fakeObj.Save()).WillReturn(true); 
    Isolate.WhenCalled(() => fakeObj.Search("sqlString")).WillReturn(true);
    Isolate.SwapNextInstance<LegacyObject>().With(fakeObj);

    // Run the real code
    CustWebService custWebService = new CustWebService();
    bool result = custWebService.DoSomeWork();
    
    // Mock verification
    Isolate.Verify.WasCalledWithAnyArguments(()=>fakeObj.VerifyRules());
    Isolate.Verify.WasCalledWithAnyArguments(()=>fakeObj.Save());
    Isolate.Verify.WasCalledWithAnyArguments(()=>fakeObj.Search("sqlString"));
    
    // Code execution assertion
    // (Technically we're testing our mocks here, but for illustration
    // purposes, we'll let it slide.)
    Assert.IsTrue(result);
  }
}


I believe the repro is faithful to the description provided... but when I run the test, it passes with no issues.

Is there something I'm missing? Can you augment the above repro to give us a fuller picture? If not, it may be that you need to email Typemock support directly and take it offline. They're really helpful folks and may be able to more readily point you in the right direction.
answered by tillig (6.7k points)
0 votes
Hi,

Any chance you can post the full declaration of the LegacyObject class?
(leave out the members just the methods without their inner implementation will do)
one thing that may confuse the isolator are overloaded methods. Can it be that the Search method has more then a single overload?
answered by error (6.6k points)
...