【问题标题】:MOQ Creating a Mock of an abstract class returns nullMOQ 创建抽象类的 Mock 返回 null
【发布时间】:2020-04-04 15:48:27
【问题描述】:

首先,我知道我的问题的标题并不适合这个问题;我只是不确定标题应该是什么。

据我所知,在使用 MOQ 创建抽象类的模拟时,如果对象的创建失败(由于异常处理或其他原因),模拟的创建将简单地返回 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&lt;SomeClass&gt;(null).Object 代替new Mock&lt;SomeClass&gt;(null)吗?
  • @nalka 我需要检查构造函数是否通过异常,因此我必须断言该对象的创建。

标签: c# nunit tdd moq


【解决方案1】:

这里没有真正需要使用最小起订量。

有时它有助于保持简单并创建一个派生类来满足所需的行为。

例如

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());
    }
}

【讨论】:

  • 我之所以不同意你的回答,只是因为这个问题是专门讨论如何用 MOQ 完成这个任务的。但我确实想让你知道,我决定走这条路。
  • @SleepyTurtle 选择权在你。一旦找到解决方案。
  • @SleepyTurtle 如果您发现答案有帮助,那么投票就可以了。
【解决方案2】:

您想使用new Mock&lt;SomeClass&gt;(null).Object 而不是使用new Mock&lt;SomeClass&gt;(null),因为构造函数仅在您第一次使用模拟对象时被调用。然后你会得到一个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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多