0

I am to write a series tests for a custom HtmlHelper.

A mocked view model is created (with no DataAnnotation):

    private sealed class MockLoginInputModel
    {
        public string Username { get; set; }
    }

Then there are a simplest test:

    [Test]
    public void SimplestLabel()
    {

        //arrange
        var sb = new StringBuilder();
        sb.Append(@"<label for=""Username"">");
        sb.Append(@"Username");
        sb.Append(@"</label>");
        var expected = sb.ToString();

        var html = HtmlHelperFactory.Create(new MockLoginInputModel());

        //act
        var result = html.WviLabelFor(m => m.Username);

        //assert
        var actualOutput = result.ToHtmlString();
        Assert.AreEqual(actualOutput, expected);
    }

After the simplest, I am to write a test to see whether the DataAnnotation features are functional.

Of course we can create another mock model with some data annotation, like:

    private sealed class MockLoginInputModel
    {
        [DisplayName("Your Username: ")]
        public string Username { get; set; }
    }

But we would have to create quite a few models for different tests.

Is there a way we can just add in the data annotation attribute

([DisplayName("Your Username: ")]) in the testing methods?

Something like:

    var model=new MockLoginInputModel();     
    model=AddDisplayName(model, "Your username:");             
    var html = HtmlHelperFactory.Create(model);
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Blaise
  • 21,314
  • 28
  • 108
  • 169
  • What you want to do can be done if you don't pre-compile the class. Are you interested in compiling classes at runtime? I only mention this because it appears you are running unit tests, and I would not recommend compiling objects at runtime on production environments. – Erik Philips Jun 06 '14 at 23:07

2 Answers2

2

You cannot do this as far as I can tell. Would be great if someone could prove me wrong.

See this question and this question.

Community
  • 1
  • 1
mxmissile
  • 11,464
  • 3
  • 53
  • 79
  • Not a solution I am seeking. But definitely help me decide not to waste more time digging. Thanks. – Blaise Jun 06 '14 at 21:29
1

Since you are running a unit-test, you could do something like:

public static readonly unformattedClass = "public class {0} {{ {1}public string MyString {{ get; set; }} }

Unit test:

[Test]
public void SimplestLabel()
{
   var className = "SimplestLabelClass";
   var dataAnnotation = "[DisplayName(\"Your Username: \")]";

   var formattedClass = string.Format(unformattedClass,
     className,
     dataAnnotation);

   var model = CreateDynamicModel(formattedClass, className);

   var html = HtmlHelperFactory.Create(model);
}

private object CreateDynamicModel(string formattedClass, string className)
{    
  object result;
  using (var csharp = new Microsoft.CSharp.CSharpCodeProvider())
  {
    var res = csharp.CompileAssemblyFromSource(
        new System.CodeDom.Compiler.CompilerParameters() 
        {  
            GenerateInMemory = true 
        }, 
        formattedClass
    );

    var classType = res.CompiledAssembly.GetType(className);

    result = Activator.CreateInstance(type);
  }

  return result;
}       
Erik Philips
  • 53,428
  • 11
  • 128
  • 150