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
Hi,
I have an Interface, ISharePointService. The mock object will be passe to a different thread and raise the events that will be attached dynamically at runtime.

In order to achive this, the only way I found was to manually create an implementation of the interface (a Stub), adding the functions to trigger a call back.

Is there a way to mock the interface and just "extend" a Mock with extra code ? Or should I just create an abstract class that implements the interface, just add my extra code and then mock that abstract class ?

Thanks
asked by bobbyangers (2.1k points)

3 Answers

0 votes
You absolutely can use Typemock Isolator to do what you're looking to do. Here's an example where I define an interface and something that consumes an object implementing the interface. In my test, you'll see that I'm setting up some expectations around the interface, but I never actually create any "stub" implementation or anything - Isolator does the heavy lifting.

public interface ISomeInterface
{
  string GetSomething();
}

public class InterfaceConsumer
{
  ISomeInterface _member;
  public InterfaceConsumer(ISomeInterface member)
  {
    this._member = member;
  }
  
  public string PassThrough()
  {
    return this._member.GetSomething();
  }
}

[TestFixture]
[VerifyMocks]
public class MyTestFixture
{
  [Test]
  public void MyTest()
  {
    string expected = "Test Value";
    ISomeInterface stub = RecorderManager.CreateMockedObject<ISomeInterface>();
    using(RecordExpectations recorder = RecorderManager.StartRecording())
    {
      string dummy = stub.GetSomething();
      recorder.Return(expected);
    }
    InterfaceConsumer consumer = new InterfaceConsumer(stub);
    string actual = consumer.PassThrough();
    Assert.AreEqual(expected, actual);
  }
}
answered by tillig (6.7k points)
0 votes
Hi,
In my problem ti's not a consumer;

public interface ISomeInterface 
{ 
  event EventHandler<EventArgs> Hello;
} 

public class Sombody : ISomeInterface
{
    event EventHandler<EventArgs> Hello;
   
   public void RaiseHello(object stateInfo)
  {
     if(null!=Hello)
        Hello(this, (EventArgs)stateInfo);
  }

}


What I need to mock is the interface plus add the "RaiseHello" function.

Is there a way using the "LastMockedEvent" and handle.Fire ?

What seem to happen is that the binding to the event is done dynamically at runtime on a different thread than the test runner .
answered by bobbyangers (2.1k points)
0 votes
I think I get what you're saying. I think. Here's an example illustrating some of the event mocking stuff. If this isn't what you mean, it might help to post a snippet of code showing what you're trying to test. That is, if you're trying to test something that uses the "Somebody" class, show that; if you're just trying to test the "RaiseHello" method to see if it raises the event, show your test and point out what you think should be working.

Note that in the below version of your sample code I had to change a couple of things to actually get it to work. I made the Hello event on the Somebody class public and I changed RaiseHello to take an EventArgs parameter instead of just object so I could avoid the cast and simplify the code a bit.

public interface ISomeInterface 
{ 
  event EventHandler<EventArgs> Hello; 
} 

public class Somebody : ISomeInterface 
{ 
  public event EventHandler<EventArgs> Hello; 

  public void RaiseHello(EventArgs stateInfo) 
  { 
    if(null != Hello)
    {
      Hello(this, stateInfo);
    }
  } 
}

[TestFixture]
[VerifyMocks]
public class MyTestFixture
{
  [Test]
  public void MyTest()
  {
    Somebody obj = new Somebody();
    EventArgs expected = new EventArgs();
    using(RecordExpectations recorder = RecorderManager.StartRecording())
    {
      // Mock the registration for the event.
      ((ISomeInterface)obj).Hello += null;
      
      // Ensure we're raising the event with the expected arg.
      obj.RaiseHello(expected);
      recorder.CheckArguments();
    }
    
    // Attach a handler that throws an exception. If this handler
    // gets called, the test will fail because of that exception.
    // (If it's not called, it proves the mocking is running.)
    ((ISomeInterface)obj).Hello += (sender, e) => { throw new NotSupportedException(); };
    
    // Raise the event.
    obj.RaiseHello(expected);
    
    // The [VerifyMocks] attribute will ensure the event was subscribed
    // to and that we called RaiseHello with the correct args.
  }
}
answered by tillig (6.7k points)
...