有没有办法断言代码块不能编译?

时间:2014-09-16 19:39:49

标签: c# mstest assert

在MS Test中,有没有办法断言代码块没有编译?让我们说我有一个对象,我想成为一个单身人士。我可能想确保此对象没有公共构造函数。有没有办法做这样的事情?

Action create = { new Logger("abc.txt") };
Assert.CompilerError(create);

我可以使用Reflection来做到这一点,但我很好奇是否有一种断言代码实际编译的方法。以下是使用Reflection进行此操作的方法:

[TestMethod]
public void OnlyPrivateConstructors()
{
    var flags = (System.Reflection.BindingFlags)int.MaxValue; //all flags
    var constructors = typeof(Logger).GetConstructors(flags);

    foreach (var item in constructors)
    {
        Assert.IsTrue(item.IsPrivate);
    }
}

3 个答案:

答案 0 :(得分:2)

MS测试运行编译代码。如果代码没有编译,则无法进行测试。

你可以通过创建一个包含相关代码块的字符串,然后让Roslyn编译它来为Roslyn做到这一点。

http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx

Pre-roslyn,您可以创建一个包含代码块的文件,然后使用System.Diagnostics.Process等对它运行csc,但这比它的价值更麻烦。

我会坚持反思,但由于内部或受保护的构造函数也允许违反单例模式,我会Assert.IsTrue(item.IsPrivate)

我也会对Assert.IsTrue(typeof(Logger).IsSealed)进行测试。我想,有点腰带和吊带裤,但就在那里。

答案 1 :(得分:1)

您可以使用CSharpCodeProvider来动态尝试编译代码,但正如Phoog所说,它可能比它的价值更麻烦:

        var compiler = new CSharpCodeProvider();

        string source = "using DLLBeingTested; \r\n" +
                        "public class DoIt {\r\n" +
                        "public void DoSomething() {\r\n" +
                        "var x =  new Logger(\"abc.txt\");\r\n" +
                        "}}" +
                        "";

        var loc = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);


        var cp = new CompilerParameters(new[] { Path.Combine(loc, "DLLBeingTested.dll") });
        cp.ReferencedAssemblies.Add("System.dll");
        cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");

        var assm = compiler.CompileAssemblyFromSource(cp, source);

        bool foundExpectedError = false;
        foreach (var err in assm.Errors)
        {
            if (err.ToString().Contains("CS0143"))
            {
                foundExpectedError = true;
            }
        }

        Assert.IsTrue(foundExpectedError);

答案 2 :(得分:0)

我认为您使反射代码过于复杂。这样可以获得相同的结果而且工作少得多,但正如phoog提到的那样,您无法编译不会编译的代码。

[TestMethod]
public void NoPrivateConstructors()
{
    Assert.IsFalse(typeof(Logger).GetConstructors(/* binding flags... */).Any());
}