RhinoMocks AAA Syntax

為{幸葍}努か 提交于 2019-12-08 02:34:34

问题


I've spent a good part of the day trying to figure out why a simple RhinoMocks test doesn't return the value I'm setting in the return. I'm sure that I'm just missing something really simple but I can't figure it out. Here's my test:

    [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();
    }

I have an interface for my SystemIO class I'm passing in a mock for that to my CopyFiles class. I'm setting an expectation on my FileCopyDatCheck method and saying that it should Return("Test"). When I step through the code, it returns a null insteaed. Any ideas what I'm missing here?

Here's my CopyFiles class Method:

    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;
        }
    }

I would think that "fileCopied" would have the Return value set by the Expect. The GetFilesForCopy returns the two files in myFileInfo. Please Help. :)

thanks in advance!


回答1:


A mock will not start returning recorded answers until it is switched to replay mode with Replay(). Stubs and mocks do no work in the same way. I have written a blog post about the difference.

Also note that you are mixing the old record-replay-verify syntax with the new arrange-act-assert syntax. With AAA, you should not use mocks and Expect. Instead, use stubs and AssertWasCalled like this:

[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"));
}

Note how setting up the behavior of stubs at the start is separate from the assertions at the end. Stub does not set any expectations.

The advantage of seperating behavior and assertions is that you can make less assertions per test, making it easier to diagnose why a test failed.




回答2:


Does the method FileCopyDateCheck really get called with the exact strings @"c:\Myprogram.txt" and @"c:\Myprogram.txt" as arguments?

I am not sure if FileInfo is doing something with c:\. Maybe it is modified to upper case C:\, which would make your expectation not working.

Maybe try an expectation which does not check for the exact argument values

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

For more details about argument constraints see: Rhino Mocks 3.5, Argument Constraints

I am pretty sure that there are also possibilities to make the expectation case insensitive.




回答3:


I think it's because your CopyvRAFiles() method isn't virtual.



来源:https://stackoverflow.com/questions/2349454/rhinomocks-aaa-syntax

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!