Home > OS >  Using 2 byte arrays in C# Unit Testing
Using 2 byte arrays in C# Unit Testing

Time:09-01

I want to write a [DataTestMethod] that uses many [DataRow]s, all containing two byte arrays. But, my problem is that the test method only uses the Data from the last row.

I have written a Test with data rows that just contains integers which works fine. And another one that containes one Byte array and some bools. But I can't get a multiple data rows with two byte arrays to work.

Working Tests:

    [DataTestMethod]
    [DataRow(1, 1, 2)]
    [DataRow(2, 2, 4)]
    [DataRow(3, 3, 6)]
    public void AddTests(int x, int y, int expected)
    {
        Assert.AreEqual(expected, x   y);
    }

    [DataRow(new byte[] { 0x00 }, false, false, false)]
    [DataRow(new byte[] { 0x00 }, true, true, false)]
    [DataRow(new byte[] { 0x00 }, false, true, false)]
    [DataRow(new byte[] { 0x00 }, true, false, false)]
    [DataTestMethod()]
    public void ByteArrayIntegerTest(byte[] key,bool ctorsign, bool tasign,bool expectfail)
    {
        var bi = new ByteArrayInteger(key, ctorsign);
        var result = bi.ToByteArray(tasign);
        if (expectfail)
        {
            CollectionAssert.AreNotEqual(key, result);
        }
        else
        {
            CollectionAssert.AreEqual(key, result);
        }
    }

Not working Test:

    [DataTestMethod]
    [DataRow(new byte[] { 0xCA, 0xFE }, new byte[] { 0xCA, 0xFE })]
    [DataRow(new byte[] { 0x00, 0xCA, 0xFE }, new byte[] { 0xCA, 0xFE })]
    [DataRow(new byte[] { 0x00, 0x00, 0xCA, 0xFE }, new byte[] { 0xCA, 0xFE })]

    public void MinimizeSerialnumberTest(byte[] serialnumber, byte[] expected)
    {
        CollectionAssert.AreEqual(expected, Util.MinimizeSerialnumber(serialnumber));
    }

With the non working test it only ever uses the last provided DataRow. There are no errors and the test runs just fine.

Does Microsoft.VisualStudio.TestTools.UnitTesting not support multiple byte arrays? Or what could be the problem?

Edit: After some more research. Could the Problem be, that DataRowAttribute takes Object, Object[] as parameters in it's constructor? Source

If so, how would I work with that?

CodePudding user response:

Edit: After some more research. Could the Problem be, that DataRowAttribute takes Object, Object[] as parameters in it's constructor?

Yes, that seems to be the case. The second parameter is params, so the compiler performs the following translations:

           first argument --      --- array of remaining arguments
                            |    |
                            v    v
DataRow(1, 2, 3) -> DataRow(1, new object[] { 2, 3 });
DataRow(1, 2)    -> DataRow(1, new object[] { 2 });

However, the compiler won't translate DataRow(1, someObjectArray) to DataRow(1, new object[] { someObjectArray }), but rather keep the object array as it is. This is necessary in case you want to actually pass an object array containing all (remaining) parameters for your test method.

Since byte[] is implicitly convertible to object[] (an unfortunate legacy left-over from the old days when we didn't have generics), it appears that

  • your byte[] is implicitly converted to an object[] and then
  • this object[] is used as the second parameter,

resulting in the following data row for your test: { 0xCA, 0xFE }, 0xCA, 0xFE (rather than the indented { 0xCA, 0xFE }, { 0xCA, 0xFE }).

If so, how would I work with that?

Explicitly wrap your second parameter in an object[]:

[DataRow(new byte[] { 0xCA, 0xFE }, new object[] { new byte[] { 0xCA, 0xFE } })]

CodePudding user response:

I think the problem was the constructor of DataRowAttribute. I changed my data rows to the following and now everything works as intended.

[DataRow(1, new byte[] { 0xCA, 0xFE }, new byte[] { 0xCA, 0xFE })]
[DataRow(2, new byte[] { 0x00, 0xCA, 0xFE }, new byte[] { 0xCA, 0xFE })]
  • Related