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
When faking a static constructor, what's the difference between calling..

Isolate.Fake.StaticConstructor(typeof(Config));


and

var fakeConfig = Isolate.Fake.Instance<Config>(Members.ReturnNulls);
Isolate.Swap.AllInstances<Config>().With(fakeConfig);


I ask because it seems if the Swap.AllInstances() pattern is followed, any attempt to call Isolate.Fake.StaticConstructor afterwards in the same test run (even in a different isolated class) will cause the following exception:

*** Static constructor for class Config cannot be faked as it has already been called

Is anyone able to explain why this happens?

Thanks
asked by Stuart Shevlin (600 points)

1 Answer

0 votes
Hi Stuart,

MSDN:
A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
A static constructor cannot be called directly.
The user has no control on when the static constructor is executed in the program.


Since the static constructor can be called only once, and we have no control over when it is called, there is a problem with running two or more test in the same test class when the class under test has a static constructor.

Typemock allows controlling the unexpected behavior of the static constructor:

1)In tests where you don't care about the actions of the static constructor (static fields init...) you should fake it using
Isolate.Fake.StaticConstructor(typeof(Foo));

*Note that this isn't a call to the static constructor but a faking action.

2)In tests where you care about the actions of the static constructor (static fields init...) you should invoke it using
Isolate.Invoke.StaticConstructor(typeof(Foo));;

*Note that this is a call to the static constructor.

**Both 1 and to should be called before faking or instantiating a class with a static constructor.

Static constructor is called when creating a new instance or faking a type that has a static constructor:
var fakeFoo = Isolate.Fake.Instance<Foo>(Members.ReturnNulls);
Isolate.Swap.AllInstances<Foo>().With(fakeFoo);

Hence, after the code above you can't fake static constructor( since it was already called ).

However, If you decorate your test class with [Isolated] attribute which resets the environment between test runs, you'll allow the static constructor to be called once per test Method.

Please let me know if it helps.
answered by alex (17k points)
...