【问题标题】:How can I use Rhino Mocks to inspect what values were passed to a method如何使用 Rhino Mocks 来检查传递给方法的值
【发布时间】:2011-03-14 19:55:12
【问题描述】:

我是 mocking 新手,我很难解决 UnitTesting 的问题。

假设我有这个代码:

public class myClass{

    private IDoStuff _doer;

    public myClass(IDoStuff doer){
        _doer = doer;
    }

    public void Go(SomeClass object){

        //do some crazy stuff to the object

        _doer.DoStuff(object) //this method is  void too
    }
}

好的,所以我想对 Go 方法进行 UNIT 测试。我不在乎 _doer 对象一旦得到它对对象做了什么。

但是,我确实想检查 _doer 对象收到了什么。

在 PSEUDO 代码中我想实现这一点:

[Test]
public void MyTest()
{
    IDoStuff doer = Mocker.Mock<IDoStuff>();
    Guid id = Guid.NewGuid();

    //test Go method
    new MyClass(doer).Go(new SomeClass(){id = id});

    Assert.AreEqual(id,MockingFramework.Method(DoStuff).GetReceived<SomeClass>().id);
}

这是否可以使用 Rhino 实现,如果可以,我该如何实现?

干杯

【问题讨论】:

    标签: c# unit-testing mocking rhino-mocks


    【解决方案1】:

    只是一个建议:

    Wim CoenenPatrick Steele 的解决方案都是正确的,但是对于第一个解决方案,当只有一个参数时非常快,测试失败时会出现错误消息。

    这是带有两个参数的函数的消息:

    IProductChecker.MustPublish(等于2,等于123X);预期 #1,实际 #0。

    现在,这两个参数中哪一个是错误的?如果参数更多呢?

    我已经用这段代码准备了测试:

    //ARRANGE
    const string CLASSCODE = "ABC";
    const string SUBCLASSCODE = "123X";
    var expected = new [] {CLASSCODE, SUBCLASSCODE};
    
    //ACT
    SUT.CallMyFunction(chkMock);
    var actual = chkMock.GetArgumentsForCallsMadeOn(m => m.MustPublish(null, null))[0];
    
    //Assert
    CollectionAssert.AreEqual(expected, actual);
    //instead of
    //chkMock.AssertWasCalled(m => m.MustPublish(Arg<string>.Is.Equal("2"), Arg<string>.Is.Equal(SUBCLASSCODE)));
    

    所以,在这种情况下,消息是:

    CollectionAssert.AreEqual 失败。 (索引 0 处的元素不匹配。)

    你好

    【讨论】:

      【解决方案2】:

      所有这些答案都提供了各种方法来做你想做的事,而且它们都有效。还有一件事需要注意。如果您需要真正“低级”​​并检查传递给任何存根/模拟方法的参数,您可以使用GetArgumentsForCallsMadeOn

      返回 object[][] 时有点混乱。你像这样使用它(假设你存根 stubber.InsertData 接受 null):

      var args = stubber.GetArgumentsForCallsMadeOn(s => s.InsertData(null));
      

      args[0] 是第一次调用 InsertData 时传递给它的参数数组。

      args[1] 是第二次调用 InsertData 时传递给它的参数数组。

      等等……

      因此,如果您想查看作为第一次调用某个方法的第二个参数传递的整数值,您可以:

      var check = (int) args[0][1];
      

      再次,我推荐之前的方法之一,但如果您需要非常沮丧和肮脏地检查参数,则可以使用此方法。

      【讨论】:

        【解决方案3】:

        我认为你拥有的东西很好,所以它会是:

        IDoStuff doer = MockRepository.GenerateMock<IDoStuff>();
        

        然后通过以下方式设置期望:

        doer.Expect(() => DoStuff(id));
        

        然后在最后:

        doer.VerifyAllExpectations();
        

        根据 Lee 的回答编辑,注意您还可以执行以下操作:

        doer.Expect(d => d.DoStuff(Arg<int>.Is.GreaterThan(5))
        

        doer.Expect(d => d.DoStuff(Arg<CustomObject>.Matches(x => x.CustomProperty == "Beef")));
        

        或类似测试,当您不希望使用 Arg 和 Arg 对象进行精确的参考比较时。

        【讨论】:

          【解决方案4】:

          使用新的 Arrange/Act/Assert 语法:

          [Test]
          public void MyTest()
          {
              // arrange
              IDoStuff doer = MockRepository.GenerateStub<IDoStuff>();
              MyClass myClass = new Myclass(doer);
              Guid id = Guid.NewGuid();
          
              // act
              myClass.Go(new SomeClass(){id = id});
          
              // assert
              doer.AssertWasCalled(x => x.DoStuff(
                  Arg<Someclass>.Matches(y => y.id == id)));
          }
          

          【讨论】:

            【解决方案5】:

            如果您只是想测试MyClass 实例是否将其参数传递给doer.Go,那么您可以设置一个期望:

            SomeClass obj = new SomeClass { id = id };
            
            doer.Expect(d => d.DoStuff(obj));
            
            //test go method
            new MyClass(doer).Go(obj);
            
            doer.VerifyAllExpectations();
            

            但是,如果您想检查它是否传递了一些可能不同的对象,并且具有某个属性的特定值,那么您可以使用约束:

            doer.Expect(d => d.DoStuff(null))
                .IgnoreArguments()
                .Constraints(Property.Value("Id", expectedId));
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-10-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-04-01
              相关资源
              最近更新 更多