-
Notifications
You must be signed in to change notification settings - Fork 26
Technical limitations
Due to the way Smocks works, there are some technical limitations that limit what you can and cannot do with Smocks.
Any variable defined outside the scope of Smock.Run
that you use inside the scope, must be either serializable or inherit from MarshalByRefObject. In the former case, the instance inside the scope will be a deserialized copy of the instance outside the scope. In the latter case, the instance inside the scope will be a proxy of the instance outside the scope. Either method has its implications and downsides. Generally speaking, it's best to avoid capturing variables in the scope of Smock.Run
unless you know what you're doing.
This will not work:
NotSerializable test = new NotSerializable();
Smock.Run(context =>
{
test.DoSomeWork();
});
This will work:
// Serializable is annotated with the [Serializable] attribute
Serializable test = new Serializable();
Smock.Run(context =>
{
test.DoSomeWork();
});
This will also work:
// Proxyable inherits from MarshalByRefObject
Proxyable test = new Proxyable();
Smock.Run(context =>
{
test.DoSomeWork();
});
Similar to the previous limitation, any value returned by Smocks must also be serializable. Smocks enforces this by only providing Smock.Run(Func<T>)
overloads for a limited set of types T
that are known to be serializable. The following scenario works:
DateTime now = Smock.Run(context =>
{
context.Setup(() => DateTime.Now).Returns(new DateTime(2000, 1, 1));
return DateTime.Now;
});
// Outputs "2000"
Console.WriteLine(now.Year);
To intercept calls to targeted methods and properties, Smocks rewrites assemblies and subsequently loads the modified copies. Should the original assembly be strong-named, the assembly will need to be signed again after modification to restore the strong-naming. Smocks currently does not support rewriting strong-named assemblies.