Visual Studio Team Test: How to unit test "?" operator with only Asserts() and not using any tool

1.8k views Asked by At

I need to write some unit test cases to test my code in C# Visual Studio Team Test framework. Below is the method I want to test:

public static ObjectID CreateObjectID(ObjectID xrmObjectID)

{

        return new ObjectID
        {
            Id = xrmAssociation.ID != null ? xrmAssociation.ID.Id : Guid.Empty;
        };
}

In the above method, I need to write unit test cases to cover the conditional statements, for example:

Id = xrmAssociation.ID != null ? xrmAssociation.ID.Id : Guid.Empty;

So I wrote the following unit test method:

namespace WebApi.Test
{
    [TestClass]
    public class ApiTest
    {
        [TestMethod]
        [ExpectedException(typeof(NullReferenceException), "A userId of null was inappropriately allowed.")]
        public void CreateObjectIDShouldCheckConditionalBranch()
        {
            Xrm.objectID Input = new Xrm.objectID();
            Input = null;
            WebApiRole.Api.CreateObjectID(Input);
            var expected = default(WebApi.ObjectID);
            Assert.IsTrue(expected == WebApi.CreateObjectID(Input), "Failed");
        }
    }
}

This test passed, but it is actually not testing what I intend to test i.e. It should assign "Guid.Empty" when "null" is being passed. It just throws the exceptions of NullReference and thus the test passes.

2

There are 2 answers

1
Alex On BEST ANSWER

I'd suggest writing one test for each separate case. That way, you can more easily tweak the testing code should requirements change.

I'd proceed like this (and I'll also take a guess and assume you're modelling Dynamics CRM, judging by the data)

[TestMethod]
public void AssociationCreationFromXrmShouldDefaultWhenAssociationHoldingIsNull()
{
    Xrm.pv_association input = new Xrmpv_association();
    input.pv_AssociationHolding = null;

    var output = PVWebApiRole.ApiModelFactory.CreateAssociationFromXrm(Input);

    // The fact that 'output' is valid should be tested separately
    Assert.AreEqual(output.AssociationHoldingId, Guid.Empty);
}
[TestMethod]
public void AssociationCreationFromXrmShouldKeepNotNullAssociationHolding()
{
    var sampleReference = new EntityReference("yourlogicalName", Guid.Parse("00000000-0000-0000-0000-000000000000"));
    Xrm.pv_association input = new Xrmpv_association();
    input.pv_AssociationHolding = sampleReference;

    var output = PVWebApiRole.ApiModelFactory.CreateAssociationFromXrm(Input);

    // The fact that 'output' is valid should be tested separately
    Assert.AreEqual(output.AssociationHoldingId, sampleReference.Id);
}            

and so on and so forth, two tests for each field, one to test the true side of the conditional and one for the false side (a couple of generic methods, one for OptionSet fields and one for EntityReference fields could be built and called several times, making the code short and fast to write).

Also, I think you should tweak CreateAssociationFromXrm to make it throw an ArgumentException if input is null (a couple tests of specifically that are of course to be written beforehand).

4
RobV On

Using the ExpectedException annotation can be risky particularly when checking for a generic exception like NullReferenceException that could be thrown in other circumstances.

It seems like what you want to do is check that a specific property is not null in which case you would be much better off using the IsNotNull() assertion e.g.

var actual = PVWebApiRole.ApiModelFactory.CreateAssociationFromXrm(Input);
Assert.IsNotNull(actual.CreatedByUserProfileId);

For general help on debugging your NullReferenceException see What is a NullReferenceException and how do I fix it?

As I already pointed out in my comments your problem is that your CreateAssociationFromXrm() method assumes the xrmAssociation parameter is non-null when it does checks like the following:

xrmAssociation.pv_CreatedByUserProfileID != null ? xrmAssociation.pv_CreatedByUserProfileID.Id : Guid.Empty

You can avoid this by adding null checks to specific conditional statements e.g.

xrmAssociation != null && xrmAssociation.pv_CreatedByUserProfileID != null ? xrmAssociation.pv_CreatedByUserProfileID.Id : Guid.Empty

Stylistic suggestion

Often it is better to disallow null inputs completely so you may actually want to check for null at the start of your method and throw an ArgumentNullException e.g.

public static Association CreateAssociationFromXrm(Xrm.pv_association xrmAssociation)
{
  if (xrmAssociation == null) throw new ArgumentNullException("xrmAssociation", "xrmAssociation cannot be null");

  // Rest of your existing logic goes here
}