This is a migrated thread and some comments may be shown as answers.

How to harness "File.Open"? What are good strategies?

3 Answers 88 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Tormod
Top achievements
Rank 2
Tormod asked on 16 Aug 2010, 08:11 AM
Hi.

My test projects have data files as part of the solution. To avoid dependencies on the file system on the CI server, I embed them in the test assembly as manifest resources. The problem is when I intercept File.Open calls using JustMock. What do I do? What do I return? Do I pass it a Mock<FileInfo>? Since "File.Open()" is mentioned about as often as "DateTime.Now" to show the strengths of TypeMock and JustMock, what are good practices/strategies to employ when dealing with it?

http://stackoverflow.com/questions/3466355/how-can-i-pass-a-solution-resource-as-a-filestream-object-to-an-intercepted-file

3 Answers, 1 is accepted

Sort by
0
Accepted
Ricky
Telerik team
answered on 16 Aug 2010, 04:33 PM
Hi  Tormod,
I prepared a sample based on your requirement and added that to the stackoverlow question that you have asked.

Just to let you know that  I found a issue with Arg.IsAny<byte[]> and the example is done with a fixed  internal version. If you are interested I can provide you the build  to the email you have specified in your Telerik account along with the Mock.Partial(..).ForAll fix  for the other System.Environment related issue.

Regards,
Mehfuz


Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Tormod
Top achievements
Rank 2
answered on 17 Aug 2010, 07:10 AM
Thanks a lot! This was definitely useful.
There was a trick there that I didn't expect. I guess I need to tune in to the power of JustMock.

After creating this object like this:
FileStream fs = (FileStream)FormatterServices.GetSafeUninitializedObject(typeof(FileStream));  

I had to read this line at least three times.
Mock.Arrange(() => fs.Write(Arg.IsAny<byte[]>(), Arg.AnyInt, Arg.AnyInt)

Can you take any single method on any running instance of any type and just mock it?
My thought was that I would create a <FileInfo> mock. And return it from statically mocked File.Open().

I still need to work out how to be able to create a FileInfo object which in actuality reads from a test project resource, but this helped me a long way. And I can fiddle around with it myself.
I don't have an immediate need for it, but I hope you get the argument Arg.Any<> clause object figured out.

For clarity and posterity in this thread I've included your solution. 

        byte[] actual = new byte[255]; 
 
       
// writing locally, can be done from resource manifest as well. 
 
       
using (StreamWriter writer = new StreamWriter(new MemoryStream(actual))) 
       
{ 
            writer
.WriteLine("Hello world"); 
            writer
.Flush(); 
       
} 
 
       
// arrange the file system. 
 
       
FileStream fs = (FileStream)FormatterServices.GetSafeUninitializedObject(typeof(FileStream)); 
 
       
// mocking the specific call and setting up expectations. 
       
Mock.Arrange(() => fs.Write(Arg.IsAny<byte[]>(), Arg.AnyInt, Arg.AnyInt)) 
           
.DoInstead((byte[] content, int offset, int len) => 
       
{ 
            actual
.CopyTo(content, offset); 
       
}); 
 
       
// return custom filestream for File.Open. 
       
Mock.Arrange(() => File.Open(Arg.AnyString, Arg.IsAny<FileMode>())).Returns(fs); 
 
 
       
// act 
       
var fileStream =  File.Open("hello.txt", FileMode.Open); 
       
byte[] fakeContent = new byte[actual.Length]; 
 
       
// original task 
        fileStream
.Write(fakeContent, 0, actual.Length); 
 
       
// assert 
       
Assert.Equal(fakeContent.Length, actual.Length); 
 
       
for (var i = 0; i < fakeContent.Length; i++) 
       
{ 
           
Assert.Equal(fakeContent[i], actual[i]); 
       
} 
0
Ricky
Telerik team
answered on 17 Aug 2010, 08:52 AM
Hello Tormod,

It's nice that things helped you a bit. About the Arg.IsAny<T>(), it is also possible to write it in the following way to ignore any arguments specified:


Mock.Arrange(() => fs.Write(null, 0, 0).IgnoreArgument();

Secondly, it is also possible to create the instance of FileStream using Mock.Create<T>() but since here we are using specifically fs.Write method, other ways like creating  the instance using FormatterServices can significantly reduce the test execution time.



Hope that helps,
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
General Discussions
Asked by
Tormod
Top achievements
Rank 2
Answers by
Ricky
Telerik team
Tormod
Top achievements
Rank 2
Share this question
or