最小起订量创建抽象的模拟 class returns null

MOQ Creating a Mock of an abstract class returns null

首先,我明白我的问题的标题不是很适合这个问题;我只是不确定标题应该是什么。

据我所知,在使用最小起订量创建抽象 class 的模拟时,如果 object 的创建失败(由于异常处理或其他原因),则创建模拟的 return null.

在我的例子中,我想检查构造函数中是否抛出了 ArgumentNullException。但是由于我上面所说的,我的测试失败了,实际结果是 null,而不是 ArgumentNullException

public abstract class SomeClass
{
    public SomeClass(ISomeDependency someDependency)
    {
        if (someDependency == null)
        {
            throw new ArgumentNullException(nameof(someDependency));
        }

        this.someDependency = someDependency;
    }
}
public sealed class LogHandlerTests
{
    [Test]
    public void Constructor_Test_Should_Throw_ArgumentNulLException_When_SomeDependency_Is_Null()
    {
            Assert.Throws<ArgumentNullException>(() => new Mock<SomeClass>(null));
    }
}

你不想使用 new Mock<SomeClass>(null) 而想使用 new Mock<SomeClass>(null).Object 因为构造函数只在你第一次使用模拟对象时被调用。然后你最终会得到一个 TargetInvocationException 因为 Moq 使用反射来实现 Mocking。这意味着您可能需要类似于

的代码
[TestClass]
public class Test
{
    [TestMethod]
    public void MyTestMethod()
    {
        Exception caughtException = null;
        try
        {
            var test = new Mock<SomeClass>(null).Object;
        }
        catch (Exception ex)
        {
            caughtException = ex;
        }

        Assert.IsInstanceOfType(caughtException.InnerException, typeof(ArgumentNullException));
    }
}

public abstract class SomeClass
{
    ISomeDependency someDependency;

    public SomeClass(ISomeDependency someDependency)
    {
        if (someDependency == null)
        {
            throw new ArgumentNullException(nameof(someDependency));
        }

        this.someDependency = someDependency;
    }
}

这里真的不需要使用 MOQ。

有时保持简单并创建派生的 class 来满足所需的行为会有所帮助。

例如

public sealed class LogHandlerTests {

    private class Subject: SomeClass {
        public Subject(): base (null) { //<-- SHOULD THROW
            //...
        }
    }

    [Test]
    public void Constructor_Test_Should_Throw_ArgumentNulLException_When_SomeDependency_Is_Null() {
        Assert.Throws<ArgumentNullException>(() => new Subject());
    }
}