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
Hi folks,

I'm doing some mocking/faking of the System Center Operations Manager API and all is going well with the exception of one place (so far...). Here's what I'm trying to fake:

var targets = serviceComponent[hasGroupRelationship.Target].ToList();

the serviceComponent variable holds a collection, which has several indexers. The one I'm using here has a signature that looks like this:

public IList<IComposableProjection> this[ManagementPackRelationshipEndpoint role] It's implemented internally as a IEnumerable<KeyValuePair<ManagementPackRelationshipEndpoint, IComposableProjection>>, so I'm passing in the key as an object here.

Here's how I'm faking it:

var fakeProjection = Isolate.Fake.Instance<EnterpriseManagementObjectProjection>(Members.ReturnRecursiveFakes); //this is the "serviceComponent" above
var fakeRelationship = Isolate.Fake.AllInstances<ManagementPackRelationship>(Members.ReturnRecursiveFakes); //this is "hasGroupRelationship" above
var fakeEndpointTarget = Isolate.Fake.Instance<ManagementPackRelationshipEndpoint>(Members.ReturnRecursiveFakes); //this is ".Target" above
var fakeGroupProjection = Isolate.Fake.Instance<EnterpriseManagementObjectProjection>(Members.ReturnRecursiveFakes); //this is what should get returned inside a List<IComposableProjection> from the top line in red

Isolate.WhenCalled(() => fakeRelationship.Target).WillReturn(fakeEndpointTarget); //fake getting the target
var target = fakeRelationship.Target; //I can't use a property in the Isolate.WhenCalled(), so I have to do this
Isolate.WhenCalled(() => fakeProjection[target]).WillReturn(new List<IComposableProjection>{ fakeGroupProjection }); //tell it to return a list with the fake projection in it

The problem is that this line

var targets = serviceComponent[hasGroupRelationship.Target].ToList();

always returns an empty list. Somehow the fakeProjection[target]).WillReturn() isn't working.

I've also tried directly adding the child projection using fakeProjection.Add(target, fakeGroupProjection), but that doesn't work, either.

Any help on this would be much appreciated, as there's a significant portion of code that I can't test hiding behind this line of code returning a list with > 0 items inside it.

Thanks,

Jack
asked by lant3rn1969 (18.4k points)

8 Answers

0 votes
Hi Jack,

We've made two significant changes in your test:

var fakeProjection = Isolate.Fake.AllInstances<EnterpriseManagementObjectProjection>();
var fakeRelationship = Isolate.Fake.AllInstances<ManagementPackRelationship>();
var fakeEndpointTarget = Isolate.Fake.Instance<ManagementPackRelationshipEndpoint>();
var fakeGroupProjection = Isolate.Fake.Instance<EnterpriseManagementObjectProjection>();

Isolate.WhenCalled(() => fakeProjection[fakeEndpointTarget]).WillReturnCollectionValuesOf(new List<IComposableProjection> { fakeGroupProjection }); 



1. We replaced the "Fake.Instances" with "AllInstances" for fakeProjection.

2. We replaced the "WillReturn" with "WillReturnCollectionValuesOf" in the "WhenCalled" statement.

Please run this test and let us know if it helps.
answered by NofarC (4k points)
0 votes
Thanks very much for the reply.

I've made the changes you suggest, but the count is still zero, as you can see in this attachment.

count = 0.jpg

Any other thoughts?
answered by lant3rn1969 (18.4k points)
0 votes
Hi,

Can you please post the If block so we can fine the most suited solution?

Thanks,
answered by NofarC (4k points)
0 votes
Is this the if block you mean?

if (serviceComponent != null)
{
    var targets = serviceComponent[hasGroupRelationship.Target].ToList(); 
    //if the component has a group
    if (targets.Count > 0) //always 0 when unit testing
    {
        //get the group that contains the environments
        var group = targets.First().Object;

        //get the environments
        var environments = _entityObjects.GetRelatedObjects<EnterpriseManagementObject>
            (group.Id, containItemsRelationship, TraversalDepth.OneLevel, ObjectQueryOptions.Default);

        //loop through the environments and check status -- only add if the environment is not pending delete
        serviceEnvironments.AddRange(from env in environments 
                                        let envStatus = Convert.ToString(env[BusinessServiceClass, General.ObjectStatus].Value) 
                                        where !envStatus.Equals(General.ObjectStatusPendingDelete, StringComparison.OrdinalIgnoreCase) 
                                        select env);

        return serviceEnvironments;
    }
}
answered by lant3rn1969 (18.4k points)
0 votes
Hi,

We thing that the problem is the Indexer.
It should be called in the test with the exact same arguments as in the code.

var fakeProjection = Isolate.Fake.AllInstances<EnterpriseManagementObjectProjection>(); 
var fakeRelationship = Isolate.Fake.AllInstances<ManagementPackRelationship>(); 
var fakeEndpointTarget =  fakeRelationship.Target;
var fakeGroupProjection = Isolate.Fake.Instance<EnterpriseManagementObjectProjection>();

Isolate.WhenCalled(() => fakeProjection[fakeEndpointTarget]).WillReturnCollectionValuesOf(new List<IComposableProjection> { fakeGroupProjection });


Please let us know if the code above solves it.
answered by alex (18k points)
0 votes
Unfortunately, no, that didn't fix it. Here's what I have now:

var fakeParentServiceProjection = Isolate.Fake.AllInstances<EnterpriseManagementObjectProjection>(Members.ReturnRecursiveFakes);
var fakeGroupProjection = Isolate.Fake.Instance<EnterpriseManagementObjectProjection>(Members.ReturnRecursiveFakes);
var fakeRelationship = Isolate.Fake.AllInstances<ManagementPackRelationship>(Members.ReturnRecursiveFakes);
var fakeEndpointTarget = fakeRelationship.Target;
var fakeEndpointSource = fakeRelationship.Source;

//these don't work
Isolate.WhenCalled(() => fakeParentServiceProjection[fakeEndpointSource]).WillReturnCollectionValuesOf(new List<IComposableProjection> { fakeGroupProjection });
Isolate.WhenCalled(() => fakeParentServiceProjection[fakeEndpointTarget]).WillReturnCollectionValuesOf(new List<IComposableProjection>{ fakeGroupProjection });

//this works
var mockProjectionReader = new ScsmMocks.ProjectionReader(new List<EnterpriseManagementObjectProjection>{fakeParentServiceProjection});
Isolate.WhenCalled(() => _fakeEntityObjects.GetObjectProjectionReader<EnterpriseManagementObject>(fakeProjectionCriteria, ObjectQueryOptions.Default))
                    .WillReturnCollectionValuesOf(mockProjectionReader);


Here's the code I'm faking (some things have changed)
var resources = new List<Resource>();

//these are faked fine
var hasGroupRelationship = _entityTypes.GetRelationshipClass(General.ServiceHasGroupRelationshipClassName, ServiceDesignerLibraryManagementPack);
var containItemsRelationship = _entityTypes.GetRelationshipClass(General.ServiceContainsRelationshipClassName, SystemLibararyManagementPack);

//Get the groups in under the service.
if (businessService != null)
{
    //get the service components projection
    //these all get faked fine
    var configMp = GetManagementPackByName(General.AvanadeCsmConfigurationManagementPackName);
    var svcProj = configMp.GetTypeProjection(General.AvanadeCsmServiceComponentsProjectionType);
    var serviceComponent = GetServiceProjectionById(businessService.Id.ToString(), ServiceDesignerLibraryManagementPack, svcProj);
    if (serviceComponent != null)
    {
        //get all the groups related to service component
        //this returns a list with length 0
        var groups = serviceComponent[hasGroupRelationship.Target].ToList();

        //if the component has a group
        //this is always false
        if (groups.Any())
        {
            foreach (var group in groups)
            {
                //Get all objects related to group
                var relatedConfigItems = _entityObjects.GetRelatedObjects<EnterpriseManagementObject>
                    (group.Object.Id, containItemsRelationship, TraversalDepth.OneLevel, ObjectQueryOptions.Default);

                resources.AddRange(relatedConfigItems.Select(emo => EntityMapper.MapResources(emo, CurrentUiCulture)).Where(resource => resource != null));
            }

            return resources;
        }
    }


Thanks,

Jack
answered by lant3rn1969 (18.4k points)
0 votes
Hello,

I am not sure if this has been resolved but our team is trying to use Typemock to test one of our data access layer requiring use to System Center Operations Manager API. I was trying to mock the instance of a EnterpriseManageGroup here's the following code:

 var mg = Isolate.Fake.Instance<EnterpriseManagementGroup>(Members.ReturnRecursiveFakes, ConstructorWillBe.Ignored); 


Unfortunately, when I try to run it I get the following exception :
"The type initializer for 'TypeMock.InterceptorsWrapper' threw an exception."

Here's the InnerException:
"Additional non-parsable characters are at the end of the string."

Here's the stack trace:
at TypeMock.InterceptorsWrapper.get_IsNearStackOverflow()
at TypeMock.MockManager.isMocked(Object context, String typeName, String methodName, Object methodParameters, Boolean isDecorated, Boolean isIntercepted)
at TypeMock.MockPainter.ShouldPaint(String typename, String method, Object context, TypeParams genericTypes)
answered by pat (140 points)
0 votes
Hi Pat,

This issue might have been caused by bad Isolator deployment on your machine.
Please uninstall Isolator and install the latest version.

If the issue persists, send me the full stack trace along with icrosoft.EnterpriseManagement.Core.dll so I can reproduce it.

Looking forward to your feedback.
answered by alex (18k points)
...