Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# + NUnit: Unit testing methods with byte array arguments

I would like to write unit tests for some classes with methods having byte array arguments. There are about 100 methods in total, and the array size ranges from 5-10 to a few 100 bytes. How should I generate and store the test arrays?

  1. Should I generate them manually or by some generator code (which should be unit tested, too)?
  2. Should I generate them in memory during the test, or should I generate them in advance and store them somewhere?
  3. In the latter case, should I store them in files (even if unit tests shouldn't touch the file system), or should I store them inside the test code itself (for example, in strings in hexadecimal format, like this: "47 08 00 14 etc.")?

I started to create them manually and store them in the test code in hex strings. I worked a lot with such binary strings, so I can read them relatively easily ("I don't even see the code. All I see is blonde, brunette, redhead.") The problem is, this approach is slow, and I think using an automatic generator would result in more maintainable tests. But how should I test that the output of the generator is correct? Sounds like Catch-22...

like image 735
kol Avatar asked Jan 13 '23 13:01

kol


2 Answers

I'm assuming you want the bytes to actually represent deserializable objects, not just be random. A hundred bytes or so would make a small base64 encoded string. You could save your test inputs as base 64 encoded strings and then the test could grab the correct one and turn it into bytes:

    const string someScenario = 
"R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==";

    byte[] bytes = Convert.FromBase64String(someScenario);

You could figure out what the string would be in advance via your serializer, something like

public string SerializeAsBase64()
{
    var session = new SessionCredentials { SessionKey = Guid.NewGuid() };

    using (var mem = new MemoryStream())
    {
        var formatter = new BinaryFormatter();
        formatter.Serialize(mem, session);

        var bytes = mem.ToArray();

        return Convert.ToBase64String(bytes);
    }
}

To make sure it works do you have a deserializer also...? to serialize then deserialize then compare the originals are equal?

like image 167
CRice Avatar answered Jan 16 '23 17:01

CRice


I suggest using Microsofts Text Templates as generator for your unit tests. Just add a .tt file to your project and implement the generator. The generation is done at design time (when you save or change your template) and results in a .cs file in your project. Your testcode can then be handled as normal 'handwritten' code with one test per byte array and method.

The generator can load definition files as well for your byte arrays and the expected output. But since it is done at design time your unit tests are not using the file system.

The whole T4 system is really worth a look: Design-Time Code generation by using T4 Text Templates

...and it is by default part of VisualStudio - no need to install anything or change your build scripts.

like image 41
frommf Avatar answered Jan 16 '23 17:01

frommf