最小起订量创建抽象的模拟 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());
}
}
首先,我明白我的问题的标题不是很适合这个问题;我只是不确定标题应该是什么。
据我所知,在使用最小起订量创建抽象 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());
}
}