简体   繁体   English

C# Nunit Moq 无法通过测试

[英]C# Nunit Moq Cannot make test pass

I have this 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))
    }
}

I also have this test:我也有这个测试:

[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!
    }
}

I don't know why but I can't get this test to pass.我不知道为什么,但我无法通过这个测试。 NCrunch is giving me the following error message: NCrunch 给我以下错误信息:

Moq.MockException : Expected invocation on the mock once, but was 0 times: m => m.DoSomethingWith("ID", .valueClass) No setups configured. Moq.MockException :预期在模拟上调用一次,但为 0 次: m => m.DoSomethingWith("ID", .valueClass) 未配置设置。

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](Mock 1 mock, Expression 1 expression, Times times, String failMessage) at Moq.Mock 1.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. 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预期,表达式表达式,次次)在 Moq.Mock.Verify[T](模拟1 mock, Expression 1 表达式,次次,字符串失败消息)在 Moq.Mock 1.Verify(Expression 1 表达式,次次)在测试。 MyClassTest.GIVEN_AnID_AND_AValue1_AND_AValue2_WHEN_DoingSomeMethod_THEN_TheSomeInterfaceShouldDoSomething() 在 C:\\MySourceCode\\File 和行号在这里。

As you can see, it seems like Moq is "not seeing" my invocation, probably because of the new ValueClass(value1, value2) how can I make this test pass or how can I change my design so it is easier to test?如您所见,Moq 似乎“没有看到”我的调用,可能是因为new ValueClass(value1, value2)我怎样才能让这个测试通过或者我怎样才能改变我的设计以便更容易测试? Where should I put the new ValueClass(value1, value2) ?我应该把new ValueClass(value1, value2)放在哪里?

EDIT:编辑:

Is this a question I should ask on Software Engineering instead of StackOverflow?这是我应该在软件工程而不是 StackOverflow 上问的问题吗? Is this out of scope?这超出范围了吗?

Your problem is not matching argument in method call: this.valueClass by default is not equal to new ValueClass(value1, value2) because it will be two different instances of ValueClass .您的问题不在于方法调用中的参数匹配:默认情况下this.valueClass不等于new ValueClass(value1, value2)因为它将是ValueClass两个不同实例。 And by default two instances will be compared by references, which are different.默认情况下,两个实例将通过引用进行比较,它们是不同的。 You can:你可以:

  • Override Equals and GetHashCode methods in ValueClass to change the way how two instances compared.覆盖ValueClass EqualsGetHashCode方法以更改两个实例的比较方式。 Ie compare by values instead of comparing by references.即按值比较而不是按引用比较。
  • Ignore this argument with It.Any<ValueClass>() .使用It.Any<ValueClass>()忽略此参数。 It's good if you don't care about specific values of ValueClass and just want to check method was called.如果您不关心ValueClass特定值而只想检查方法是否被调用, ValueClass Not always best option并不总是最好的选择
  • Use predicate to check values of ValueClass manually: It.Is<ValueClass>(vc => vc.Value1 == VALUE1 && vc.Value2 == VALUE2) .使用谓词手动检查ValueClass值: It.Is<ValueClass>(vc => vc.Value1 == VALUE1 && vc.Value2 == VALUE2) Sometimes it's also good.有时也不错。 Eg if you cannot override Equals .例如,如果您不能覆盖Equals But it makes tests much less readable.但它使测试的可读性大大降低。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM