3

I'm writing unit tests for a class that uses XConnectClient, which means I need to mock an XConnectClient.

I've tried the following using Moq and RandomTestValues packages:

Mock<XConnectClient> client = new Mock<XConnectClient>(
    new Mock<XConnectClientConfiguration>(
        new Mock<XdbModel>(
            "XdbName",
            new XdbModelVersion(RandomValue.Int(), RandomValue.Int()),
            new XdbNamedType[0],
            new XdbFacetDefinition[0],
            new XdbModel[0]).Object,
        new Mock<Uri>(RandomValue.Uri().ToString()).Object).Object);

This compiles, but generates a NullReferenceException in XConnectClientConfiguration.ctor at runtime. I don't know what is NULL here, and there's really too much going on in the mocking so it's not easily readable any more.

Is there a way of mocking XConnectClient (preferrably without having to write a wrapper around it)?

1 Answer 1

3

I was able to run your code by not mocking Uri, but by

                Mock<XConnectClient> client = new Mock<XConnectClient>(
                new Mock<XConnectClientConfiguration>(
                    new Mock<XdbModel>(
                        "XdbName",
                        new XdbModelVersion(1, 0),
                        new XdbNamedType[0],
                        new XdbFacetDefinition[0],
                        new XdbModel[0]).Object,
                    new Uri("https://dummy.xconnect")).Object);

However, if your intention is to verify returned contacts/interactions, then it won't help as those properties cannot be overridden on xConnectClient:

            /* 'Unsupported expression: x => x.Contacts
                Non-overridable members (here: XdbContext.get_Contacts) may not be used in setup / verification expressions.'
            */
            client.Setup(x => x.Contacts).Returns(new List<Contact>
            {
                new Contact(new ContactIdentifier("test", "1", ContactIdentifierType.Anonymous))
            }.ToAsyncEnumerable().AsAsyncQueryable());

A better option to consider would be to mock IXdbContext that XConnectClient implements:

            var client2 = new Mock<IXdbContext>();
            client2.Setup(cn => cn.Contacts).Returns(new List<Contact>
            {
                new Contact(new ContactIdentifier("test", "1", ContactIdentifierType.Anonymous))
            }.ToAsyncEnumerable().AsAsyncQueryable());
            
            var c = client2.Object.Contacts;
            Console.WriteLine(c.Count().Result);
            
            c.ForEach(contact => 
                Console.WriteLine(string.Join(",", contact.Identifiers.Select(id => id.Source))));
2
  • Thanks for the IXdbContext suggestion. That looks like exactly the way I need to go :) Nov 13, 2020 at 14:51
  • @GTHvidsten good to hear that you found it helpful :)
    – grg
    Nov 14, 2020 at 9:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.