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
takesObject, 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 anobject[]
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 })]