C# Nunit Moq 无法通过测试
C# Nunit Moq Cannot make test pass
我有这个class:
class MyClass
{
private ISomeInterface blabla;
public MyClass() : this(new SomeInterfaceImplementation()) {}
internal MyClass(ISomeInterface blabla)
{
this.blabla = blabla;
}
public void SomeMethod(string id, int value1, int value2)
{
this.blabla.DoSomethingWith(id, new ValueClass(value1, value2))
}
}
我也有这个测试:
[TestFixture]
public class MyClassTest
{
private const string ID = "id";
private const int VALUE1 = 1;
private const int VALUE2 = 2;
private ValueClass valueClass;
private Mock<ISomeInterface> mockInterface;
private MyClass myClass;
[SetUp]
public void SetUp()
{
this.valueClass = new ValueClass(VALUE1, VALUE2);
this.mockInterface = new Mock<ISomeInterface>();
this.myClass = new MyClass(this.mockInterface.Object);
}
[Test]
public void GIVEN_AnID_AND_AValue1_AND_AValue2_WHEN_DoingSomeMethod_THEN_TheSomeInterfaceShouldDoSomething()
{
this.myClass.SomeMethod(ID, VALUE1, VALUE2);
this.mockInterface.Verify(m => m.DoSomethingWith(ID, this.valueClass), Times.Once()); //<- Test fails here!
}
}
我不知道为什么,但我无法通过此测试。 NCrunch 给我以下错误消息:
Moq.MockException : Expected invocation on the mock once, but was 0
times: m => m.DoSomethingWith("ID", .valueClass) No setups
configured.
Performed invocations:
ISomeInterface.DoSomethingWith("ID",
MyNamespace.ValueClass) at
Moq.Mock.ThrowVerifyException(MethodCall expected, IEnumerable1
setups, IEnumerable
1 actualCalls, Expression expression, Times times,
Int32 callCount) at Moq.Mock.VerifyCalls(Interceptor
targetInterceptor, MethodCall expected, Expression expression, Times
times) at Moq.Mock.Verify[T](Mock1 mock, Expression
1 expression,
Times times, String failMessage) at Moq.Mock1.Verify(Expression
1
expression, Times times) at
Tests.MyClassTest.GIVEN_AnID_AND_AValue1_AND_AValue2_WHEN_DoingSomeMethod_THEN_TheSomeInterfaceShouldDoSomething()
in
C:\MySourceCode\File and line number here.
如您所见,似乎起订量是 "not seeing" 我的调用,可能是因为 new ValueClass(value1, value2)
我怎样才能使这个测试通过,或者我怎样才能改变我的设计,以便更容易去测试?我应该把 new ValueClass(value1, value2)
放在哪里?
编辑:
我应该在软件工程而不是 Whosebug 上问这个问题吗?这超出范围了吗?
您的问题是方法调用中的参数不匹配:默认情况下 this.valueClass
不等于 new ValueClass(value1, value2)
,因为它将是 ValueClass
的两个不同实例。默认情况下,两个实例将通过不同的引用进行比较。您可以:
- 覆盖
ValueClass
中的 Equals
和 GetHashCode
方法以更改两个实例的比较方式。 IE。按值比较而不是按引用比较。
- 用
It.Any<ValueClass>()
忽略这个参数。如果您不关心 ValueClass
的具体值并且只想检查调用的方法,那很好。并不总是最好的选择
- 使用谓词手动检查
ValueClass
的值:It.Is<ValueClass>(vc => vc.Value1 == VALUE1 && vc.Value2 == VALUE2)
。有时候也很好。例如。如果您无法覆盖 Equals
。但它使测试的可读性大大降低。
我有这个class:
class MyClass
{
private ISomeInterface blabla;
public MyClass() : this(new SomeInterfaceImplementation()) {}
internal MyClass(ISomeInterface blabla)
{
this.blabla = blabla;
}
public void SomeMethod(string id, int value1, int value2)
{
this.blabla.DoSomethingWith(id, new ValueClass(value1, value2))
}
}
我也有这个测试:
[TestFixture]
public class MyClassTest
{
private const string ID = "id";
private const int VALUE1 = 1;
private const int VALUE2 = 2;
private ValueClass valueClass;
private Mock<ISomeInterface> mockInterface;
private MyClass myClass;
[SetUp]
public void SetUp()
{
this.valueClass = new ValueClass(VALUE1, VALUE2);
this.mockInterface = new Mock<ISomeInterface>();
this.myClass = new MyClass(this.mockInterface.Object);
}
[Test]
public void GIVEN_AnID_AND_AValue1_AND_AValue2_WHEN_DoingSomeMethod_THEN_TheSomeInterfaceShouldDoSomething()
{
this.myClass.SomeMethod(ID, VALUE1, VALUE2);
this.mockInterface.Verify(m => m.DoSomethingWith(ID, this.valueClass), Times.Once()); //<- Test fails here!
}
}
我不知道为什么,但我无法通过此测试。 NCrunch 给我以下错误消息:
Moq.MockException : Expected invocation on the mock once, but was 0 times: m => m.DoSomethingWith("ID", .valueClass) No setups configured.
Performed invocations:
ISomeInterface.DoSomethingWith("ID", MyNamespace.ValueClass) at Moq.Mock.ThrowVerifyException(MethodCall expected, IEnumerable
1 setups, IEnumerable
1 actualCalls, Expression expression, Times times, Int32 callCount) at Moq.Mock.VerifyCalls(Interceptor targetInterceptor, MethodCall expected, Expression expression, Times times) at Moq.Mock.Verify[T](Mock1 mock, Expression
1 expression, Times times, String failMessage) at Moq.Mock1.Verify(Expression
1 expression, Times times) at Tests.MyClassTest.GIVEN_AnID_AND_AValue1_AND_AValue2_WHEN_DoingSomeMethod_THEN_TheSomeInterfaceShouldDoSomething() in C:\MySourceCode\File and line number here.
如您所见,似乎起订量是 "not seeing" 我的调用,可能是因为 new ValueClass(value1, value2)
我怎样才能使这个测试通过,或者我怎样才能改变我的设计,以便更容易去测试?我应该把 new ValueClass(value1, value2)
放在哪里?
编辑:
我应该在软件工程而不是 Whosebug 上问这个问题吗?这超出范围了吗?
您的问题是方法调用中的参数不匹配:默认情况下 this.valueClass
不等于 new ValueClass(value1, value2)
,因为它将是 ValueClass
的两个不同实例。默认情况下,两个实例将通过不同的引用进行比较。您可以:
- 覆盖
ValueClass
中的Equals
和GetHashCode
方法以更改两个实例的比较方式。 IE。按值比较而不是按引用比较。 - 用
It.Any<ValueClass>()
忽略这个参数。如果您不关心ValueClass
的具体值并且只想检查调用的方法,那很好。并不总是最好的选择 - 使用谓词手动检查
ValueClass
的值:It.Is<ValueClass>(vc => vc.Value1 == VALUE1 && vc.Value2 == VALUE2)
。有时候也很好。例如。如果您无法覆盖Equals
。但它使测试的可读性大大降低。