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
I have to mock a COM-Object, which is released by calling

System.Runtime.InteropServices.Marshal.ReleaseComObject(_myMockObject);

How can i do this? Is there any possibility to expect this?
asked by Kelloggs (1.3k points)

7 Answers

0 votes
Hi,

When you mock a COM object, you actually mock the interop calls. So there's no real need to call Release, since the COM object is not really loaded.

The question is what exactly do you want to achieve. Can you post a sample code for the test? I can give a better explanation, once I understand where you're going with this.

Thanks,
answered by gilz (14.5k points)
0 votes
I have to test code, which i am not allowed to change. The problem ist, that the COM-Objects are not only initialized within the method, but also released. An Example looks like that:

public Info GetInfo()
{
            Info myInfo = new Info();


            using (Framework myFramework = Kernel.GetService<Framework>())
            {
                try
                {
                    // the COM-Object is initialized
                    aThing it = (aThing) myFramework.aThing;

                    // Do something
                }
                catch (COMException exception)
                {
                    // Do something
                }
                finally
                {
                    // ... and released
                    Marshal.ReleaseComObject(it);
                }
            }
            return Info;
}


If i am mocking the aThing-Type, it throws an ArgumentException, when Marshal tries to release it. I have no idea how i could solve this problem without changing the implementation of the method. Is there any possibility?
answered by Kelloggs (1.3k points)
0 votes
Hi,

Ok, we need to get to the bottom of this.

First, according to MS documentation, you get an ArgumentException when what you try to release is null or not a COM object. Check if you call this on the original reference it also happens, and if you're not passing null by mistake.

Can you post the stack and output of the exception? It might be there's some information that can help us investigate. If you can create a solution reproducing the problem, this would be even better. If you can we'll go offline, and move our conversation to emails and attachments.

Thanks,
answered by gilz (14.5k points)
0 votes
I verified, that the object passed to Marshal is my Mock-Object. When passed to Marshal, do all Properties of the Mock-Object have to be set?

I have not found any information on how Marshal is exactly releasing the COM-Object.

Setting Expectations for all properties and variables of the mocked Object would be a lot of work, because it is quite similar of what is called god class.

The Exception details are the following:

System.ArgumentException was unhandled
  Message="Der Objekttyp muss __ComObject sein oder von __ComObject abgeleitet werden.
Parametername: o"
  Source="mscorlib"
  ParamName="o"
  StackTrace:
       bei System.Runtime.InteropServices.Marshal.ReleaseComObject(Object o)
       bei Lock.Unlock() in D:..Path..Lock.cs:Zeile 194.
       bei Lock.Dispose(Boolean disposing) in D:PathLock.cs:Zeile 240.
       bei Lock.Finalize() in D:..Path..Lock.cs:Zeile 253.


...which looks not very helpful to me.

I am a student trying to develop a proof of concept on how to do unit testing for a company and i am actually working with the trial version of TypeMock, which is so far the best possibility to unit test the code i have found. I am not allowed to post or send any productive code and trying to reengineer a dummy-solution would mean reinventing the wheel.
answered by Kelloggs (1.3k points)
0 votes
System.ArgumentException was unhandled
  Message="Der Objekttyp muss __ComObject sein oder von __ComObject abgeleitet werden.
Parametername: o"



I forgot: this means

"The type of the object has to be __ComObject or derived from it"
answered by Kelloggs (1.3k points)
0 votes
Hi,

Ok, I'm still not sure, so let's explore a bit more.

1. Do you call the ReleaseComObject directly (like in your first sample) or is it called from a finalizer thread at the end of the test? ( I ask because of the finalizer I saw on the stack).

2. If you call it directly, what happens if you don't? (which, if works, could be a workaround).

I guess you're asking about the properties because of the argument exception? The properties do not have to be set before sending it to Marshal. Can you post your mocking code?

Let's continue from there.
answered by gilz (14.5k points)
0 votes
Hi gilz,

1. Do you call the ReleaseComObject directly (like in your first sample) or is it called from a finalizer thread at the end of the test? ( I ask because of the finalizer I saw on the stack).


I came across both versions. Sometimes Marshal-Release is called directly, sometimes in a finalizer of the ObjectInstance which holds a reference to the Com-Object. In both cases, the Object is not released, because it is a mock and not typeof System.__ComObject.

Is there any way i could "cast" the mocked object into a Com-Object?

2. If you call it directly, what happens if you don't? (which, if works, could be a workaround).


Like i said, even if i call it directly, for example at the end of my test method, the Exception is thrown. But like i said - the Marshal is not called within my test, but within the method or class i have to test.

I guess you're asking about the properties because of the argument exception? The properties do not have to be set before sending it to Marshal.


Yes, thats why i asked.

Can you post your mocking code?


Think it would be actual easier if i would send you an email with an example. How is your contact? Or just write me a short message i can reply to ( mail-at-jenscornelis-dot-de ).

Thanks in advance!
answered by Kelloggs (1.3k points)
...