chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi,
I followed the documentation and tried:
/*1*/ Isolate.Fake.StaticMethods(typeof(File));
/*2*/ Isolate.WhenCalled(() => File.Exists("")).WillReturn(true);

And got an exception from line 2:
A first chance exception of type 'System.NullReferenceException' occurred in Typemock.ArrangeActAssert.dll
A first chance exception of type 'System.NullReferenceException' occurred in TypeMock.dll

Any suggestions?
asked by soguy (1.8k points)

9 Answers

0 votes
File is part of MSCorLib (like all System.IO) and as such cannot be faked by Isolator.

Until we add MsCorLib faking to Isolator I suggest that you use a wrapper class around all file oprtation and fake it instead.
answered by dhelper (11.9k points)
0 votes
So assuming I don't have the option to modify production code implementation, I can't use TypeMock for testing such code?

Thanks.
answered by soguy (1.8k points)
0 votes
Faking MSCorLib objects is one of our reuired features - we'll probably add it in the future
answered by dhelper (11.9k points)
0 votes
And what about static readonly member:
public static class Constants { public static readonly string Path = "xxx"; }

I want to fake this class and this member also. I tried:
Isolate.Fake.StaticMethods(typeof(Constants));
Isolate.WhenCalled(() => Constants.Path).WillReturn("yyy");

And got:
A first chance exception of type 'System.TypeInitializationException' occurred in Test.zzz.dll
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
A first chance exception of type 'System.TypeInitializationException' occurred in TypeMock.dll
answered by soguy (1.8k points)
0 votes
it almost sounds like your trying to test with to much specifics; generally when you find yourself in these type of spots, you'll find that your testing at too low of level and there's often a much easier test you can do that doesn't require that level of testing.

For instance if you are just checking that a file is being saved to a particular location in a path, your really not testing anything except the core .NET framework; Create(path) is going to work unless you have a bad path, but since you have that below as a constant (static readonly string being set at declaration is the same as const string), it might be helpful to know what you are trying to test.
answered by boo (21.8k points)
0 votes
the reason I want to fake this readonly member and File class is because they are "external" resources. I don't need to test them.

1. The production method I want to test, calls:
if File.Exists(Constants.Path) {...here is the code I want to test...}
// "Constants" is a static class, "Path" is a static readonly member in this class

I don't mind what is the path or if the file really exists, so I wanted to fake it and return "true" always in this test.

2. The public static readonly member (right, similar to constant) is the path and I really don't care what is the path for the test. The problem is that in the production code, this member is initialized with a call to another member which calls a method in another assembly:

//static "Constants" class
public static readonly string ExternalPath = System.IO.Path.Combine(AnotherAsm.Utility.ExtPath, "xxx");
public static readonly string Path = System.IO.Path.Combine(ExternalPath, "blabla.xml");
//Code under test calls the "Path" member

//non-static "Utility" class in AnotherAsm assembly
public static string ExtPath {get {(...real implementation here...)}};

My intention was a high level of test, this is why I wanted to eliminate dependencies of "external" resources.

I hope now it's clearer...
answered by soguy (1.8k points)
0 votes
The Constants.Path seems to be a field. AAA doesn't cannot fake field behavior at the moment. you have two options:
1. Fake the getter property that calls that field
2. Use older API - Mock.MockField instead

Note that you cannot mix AAA with old API (Natural/Reflective mocks) calls in the same test.
answered by dhelper (11.9k points)
0 votes
If it was me, to make it simple to test, I would add this method:

public static bool DoesFileExist(string path)
{
    return File.Exists(path);
}


So now your code would be the below instead of what you have in your code snippet:
if(DoesFileExist(Constants.Path))
{
     //code you want to test here
}


By doing this you can now fake the static method DoesFileExist to return true or false (depending on what you want to test) and you don't need to worry about System.IO.File.Exists being called.

It stinks that you have to add 1 single method to add the level of indirection, but it's an easy work-around until Isolator tests against MSCORLIB. As a bonus, if you do are currently doing this check of File.Exists in several places and change to DoesFileExist, should you change your logic for resolving paths, it will all be in one place versus everywhere your read-only fields are now (might be a way for you to get rid of your read-only fields if you so desired)...but that's probably more answer than what you wanted; sorry. :?

If you concerned about it being public you can make it internal and use InternalsVisibleTo or make it private and use the NonPublic style.

HTH, sorry if I gave you more answer than you wanted. :D
answered by boo (21.8k points)
0 votes
boo,
Nice answer, I would go another step and make it an extension method.

public static bool FileExist(this string path)
{
    return File.Exists(path);
}


which can then be used as
if(Constants.Path.FileExist())
{
     //code you want to test here
}
answered by eli (5.7k points)
...