0

I'm using NJsonSchema to validate JSON input.

I have a small class that takes a collection of ValidationError objects and creates more user friendly error messages using the contents of each validation error.

I want to be able to write unit tests for this class, however I have came across a problem. One of the message handlers within my class has the responsibility of handling NotInEnumeration errors, and for this it uses the Enumeration property within the JsonSchema4 object held within the ValidationError and creates a nicely formatted error message.

When writing a test for this particular handler I discovered that the following is illegal:

JsonSchema4 enumSchema = new JsonSchema4();
enumSchema.Enumeration = new List<object>{ "A", "B", "C" };

This is because the Enumeration property has an internal setter.

I need to be able to set the enumeration of a validation error as the object needs to be passed through to the ValidationError's constructor, which is then read later on by my handler, as below.

private string NotInEnumerationHandler(ValidationError error)
        {
            var userFriendlyErrorString = "Answer must be within range: ";
            var enumString = "[" + string.Join<object>(", ", error.Schema.Enumeration) + "]";
            userFriendlyErrorString += enumString;
            return userFriendlyErrorString;
        }

I cannot mock the JsonSchema4 object using moq as moq doesn't allow mocking of non-virtual methods.

Essentially the details aren't really important, but I'd like to know if there's any way of setting an internal setter so that I can test this particular method within my class.

Jake12342134
  • 1,539
  • 1
  • 18
  • 45

3 Answers3

1

JsonSchema4.Enumeration is an ICollection<Object> .

Therefore I don't need to set the value of Enumeration to a new colletion, I can just add the items I want into the existing one.

Jake12342134
  • 1,539
  • 1
  • 18
  • 45
0

You can use reflection to set, first you need to get the property info of the property and then set the value to the instance you created.

var enumSchema = new JsonSchema4();
var propertyInfo = typeof(JsonSchema4).GetProperty("Enumeration", BindingFlags.Public | BindingFlags.Instance);
propertyInfo.SetValue(enumSchema, new List<object> { "A", "B", "C" });

And this is how you can verify it worked

Console.WriteLine(propertyInfo.GetValue(enumSchema, null));

You could make some extension method to provide you the "Enumeration" property in your test assembly.

Janne Matikainen
  • 5,061
  • 15
  • 21
0

This is not a complete answer, I just had too much to put in a comment and also it doesn't format correctly. Here's a sample of what your AssemblyInfo.cs should look like:

using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: AssemblyTitle("Assembly.Fully.Qualified.Name")]
[assembly: AssemblyDescription("")]

#if DEBUG
[assembly: InternalsVisibleTo("Assembly.Fully.Qualified.Name")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
#endif

You need the bottom of the two Attributes DynamicProxyGenAssembly2 in order for Moq to be able to see the internals. You might not need a Debug and Release switch in which case don't bother with the #if DEBUG section.

Coops
  • 271
  • 3
  • 7