5

I'm new to C# unit testing and xUnit. What is the correct way to test byte[] array?

I'm trying to test raw packet to object to raw packet again.

[Fact]
public void DiscoverTest()
{
    // DHCP Discover packet (#1) from 
    // https://wiki.wireshark.org/DHCP
    // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=view&target=dhcp.pcap
    // Ethernet and UDP metadata stripped
    byte[] b = new byte[]
    {
       0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x3d, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x0b, 0x82, 0x01, 0xfc, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
       0x53, 0x63, 0x35, 0x01, 0x01, 0x3d, 0x07, 0x01, 0x00, 0x0b, 0x82, 0x01, 0xfc, 0x42,
       0x32, 0x04, 0x00, 0x00, 0x00, 0x00, 0x37, 0x04, 0x01, 0x03, 0x06, 0x2a, 0xff, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    // raw byte[] to object's properties etc
    DHCPPacket p = new DHCPPacket(b);

    // p.GetRawBytes() object properties etc to raw byte[]
    Assert.Equal<byte[]>(b, p.GetRawBytes());
}

This gives:

Assert.Equal() Failure
Expected: Byte[] [1, 1, 6, 0, 0, ...]
Actual:   Byte[] [1, 1, 6, 0, 0, ...]

So I can't see in which offset data is actually wrong.

What's the correct way?

I'm using xUnit 2.2.0.

1
  • Asserting that two objects are equal uses their default equality comparer. Since byte[] doesn't override .Equals, you are comparing the references of the byte arrays, not their contents. If you want to compare the contents, you'll have to loop through them yourself or convert them to strings with BitConverter or the like. Commented Dec 22, 2017 at 15:32

2 Answers 2

3

So as pointed out in comments the array must be iterated:

byte[] pb = new DHCPPacket(b).GetRawBytes();

for (int i = 0; i < b.Length; i++)
{
    byte expected = b[i];
    byte actual = pb[i];

    Assert.True(expected == actual, 
        String.Format("Expected: '{0}', Actual: '{1}' at offset {2}.", (byte)expected, (byte)actual, i)
    );
}
Sign up to request clarification or add additional context in comments.

Comments

1

Unit tests in XUnit fail on the first assertion. You'll be able to tell which length is off if you do you Length assert first.

Assert.Equal(b.Length, p.GetRawBytes().Length);
Assert.Equal<byte[]>(b, p.GetRawBytes());

Assert.Equal takes an optional third parameter as well that prints when a test fails. So you can say:

Assert.Equal(b.Length, p.GetRawBytes().Length, $"Byte array lengths different. Expected: {b.length}, Actual: {p.GetRawBytes().Length}");

3 Comments

In this case length is correct but the raw byte[] data is incorrect after offset X. So I would like to see a diff off the arrays or offset of the first incorrect byte so I can find the culprit in the GetRawBytes method. I removed the extra length check assert in this example.
@raspi at least you can provide your own message, so you can construct your message in a way that shows what exactly is different at which offset
I think in order to do that, you'd have to iterate over each byte array and see which one was different.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.