2

我花了一天的大部分时间试图弄清楚为什么一个简单的 RhinoMocks 测试没有返回我在返回中设置的值。我确定我只是错过了一些非常简单的东西,但我无法弄清楚。这是我的测试:

    [TestMethod]
    public void CopyvRAFiles_ShouldCallCopyvRAFiles_ShouldReturnTrue2()
    {
        FileInfo fi = new FileInfo(@"c:\Myprogram.txt");
        FileInfo[] myFileInfo = new FileInfo[2];
        myFileInfo[0] = fi;
        myFileInfo[1] = fi;
        var mockSystemIO = MockRepository.GenerateMock<ISystemIO>();
        mockSystemIO.Stub(x => x.GetFilesForCopy("c:")).Return(myFileInfo);
        mockSystemIO.Expect(y => y.FileCopyDateCheck(@"c:\Myprogram.txt", @"c:\Myprogram.txt")).Return("Test");
        CopyFiles copy = new CopyFiles(mockSystemIO);

        List<string> retValue = copy.CopyvRAFiles("c:", "c:", new AdminWindowViewModel(vRASharedData));
        mockSystemIO.VerifyAllExpectations();
    }

我的 SystemIO 类有一个接口,我正在将一个模拟传递给我的 CopyFiles 类。我对我的 FileCopyDatCheck 方法设置了一个期望,并说它应该返回(“测试”)。当我单步执行代码时,它会返回一个空值。有什么想法我在这里想念的吗?

这是我的 CopyFiles 类方法:

    public List<string> CopyvRAFiles(string currentDirectoryPath, string destPath, AdminWindowViewModel adminWindowViewModel)
    {
        string fileCopied;
        List<string> filesCopied = new List<string>();
        try
        {
            sysIO.CreateDirectoryIfNotExist(destPath);

            FileInfo[] files = sysIO.GetFilesForCopy(currentDirectoryPath);

            if (files != null)
            {
                foreach (FileInfo file in files)
                {
                    fileCopied = sysIO.FileCopyDateCheck(file.FullName, destPath + file.Name);
                    filesCopied.Add(fileCopied);
                }
            }

            //adminWindowViewModel.CheckFilesThatRequireSystemUpdate(filesCopied);

            return filesCopied;
        }
        catch (Exception ex)
        {
            ExceptionPolicy.HandleException(ex, "vRAClientPolicy");
            Console.WriteLine("{0} Exception caught.", ex);

            ShowErrorMessageDialog(ex);
            return null;
        }
    }

我认为“fileCopied”将具有由 Expect 设置的返回值。GetFilesForCopy 返回 myFileInfo 中的两个文件。请帮忙。:)

提前致谢!

4

3 回答 3

7

在使用切换到重播模式之前,模拟不会开始返回记录的答案Replay()。存根和模拟的工作方式不同。我写了一篇关于差异的博客文章。

另请注意,您将旧的 record-replay-verify 语法与新的arrange-act-assert 语法混合在一起。对于 AAA,您不应使用模拟和Expect. 相反,使用存根,AssertWasCalled如下所示:

[TestMethod]
public void CopyvRAFiles_ShouldCallCopyvRAFiles_ShouldReturnTrue2()
{
    // arrange
    FileInfo fi = new FileInfo(@"c:\Myprogram.txt");
    FileInfo[] myFileInfo = new FileInfo[2];
    myFileInfo[0] = fi;
    myFileInfo[1] = fi;

    var stubSystemIO = MockRepository.GenerateStub<ISystemIO>();
    stubSystemIO.Stub(
        x => x.GetFilesForCopy(Arg<string>.Is.Anything)).Return(myFileInfo);
    stubSystemIO.Stub(
        y => y.FileCopyDateCheck(
            Arg<string>.Is.Anything, Arg<string>.Is.Anything)).Return("Test");

    CopyFiles copy = new CopyFiles(mockSystemIO);

    // act
    List<string> retValue = copy.CopyvRAFiles(
        "c:", "c:", new AdminWindowViewModel(vRASharedData));

    // make assertions here about return values, state of objects, stub usage
    stubSystemIO.AssertWasCalled(
        y => y.FileCopyDateCheck(@"c:\Myprogram.txt", @"c:\Myprogram.txt"));
}

请注意,如何在开始时设置存根的行为与最后的断言是分开的。Stub没有设定任何期望。

将行为和断言分开的优点是您可以减少每次测试的断言,从而更容易诊断测试失败的原因。

于 2010-02-28T11:16:15.253 回答
1

该方法是否FileCopyDateCheck真的被使用确切的字符串@"c:\Myprogram.txt"@"c:\Myprogram.txt"作为参数调用?

我不确定是否FileInfo正在使用c:\. 也许它被修改为大写C:\,这会使您的期望不起作用。

也许尝试一个不检查确切参数值的期望

mockSystemIO.Expect(y => y.FileCopyDateCheck(Arg<string>.Is.Anything, Arg<string>.Is.Anything)).Return("Test");

有关参数约束的更多详细信息,请参阅:Rhino Mocks 3.5,参数约束

我很确定也有可能使期望不区分大小写。

于 2010-02-28T12:31:33.500 回答
0

我认为这是因为您的 CopyvRAFiles() 方法不是虚拟的。

于 2010-03-23T01:28:44.443 回答