I'm new to Pex and Moles and i want to make use of parametrized unit tests. I am using constructor injection and I want to create a moles stub for my parameter.
public UserLogic(IUserRepository userRepository)
{
_userRepository = userRepository;
}
The documentation Ive read says Moles will generate a stub type for my repository of SIUserRepository. But I cant figure out how to generate the stub. Would anyone be able to provide an example. Thanks
I'll assume you haven't gotten as far as creating a Moles assembly yet. Here's some basic steps to follow;
in your unit test project, expand the references, and right-click the assembly which contains the type IUserRepository - select 'Add Moles Assembly';
you'll now have Moles stubs & moles available for that assembly, under a '.Moles' namespace, so if you had MyAsssembly.SomeNamespace.IUserRepository, you'll now have a stub type available as MyAssembly.SomeNameSpace.Moles.SUserRepository
Now, in some UserLogic_Test method, you can refer to the stub like so;
[TestMethod]
public void UserLogic_Test()
{
MyAssembly.SomeNameSpace.Moles.SUserRepository mock = new SUserRepository();
UserLogic o = new UserLogic(mock);
Assert.AreEqual(1, o.SomeMethod());
}
Related
We're refactoring an older system to use DI. Sadly, some of the "core" components that are used all over everywhere have injection unfriendly constructors (descriptions, for example), so we have to use ServiceLocator to create them. Refactoring them is very impractical at this time.
We're trying to create the unfriendly classes by injecting ILifetimeScope into the appropriate place, but are getting the following exception:
No constructors on type 'Autofac.Core.Registration.ScopeRestrictedRegistry' can be found with the constructor finder 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'.
If I cheat and use the "Update" method on the ContainerBuilder and then register the container as the LifetimeScope, the resolution works successfully, however, given that Update is obsolete, it's not something I want to do.
Can anyone help?
Edit: I'm not doing anything special. Build up is standard:
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
this.Container = builder.Build();
builder = new ContainerBuilder();
builder.RegisterInstance(this.Container);
builder.RegisterInstance(this.Container).As<ILifetimeScope>();
builder.Update(this.Container);
Without these lines
builder = new ContainerBuilder();
builder.RegisterInstance(this.Container);
builder.RegisterInstance(this.Container).As<ILifetimeScope>();
builder.Update(this.Container);
any class with an ILifetimeScope dependency fails with the error above.
public class MyClass : IMyClass
{
public MyClass(ILifetimeScope scope)
{
...
}
}
I'm actually thinking that this is a bug in the Autofac Framework, so I'm hoping that someone from the team will be able to tell me more.
ILifetimeScope is supposed to automatically be available.
I try to start unit testing a mid size Xtext project.
The generator currently relies on some external resources that I would like to mock inside my test. Thus, I inject the needed object via #Inject into the Generator class.
e.g in pseudocode:
class MyGenerator implements IGenerator{
#Inject
ExternalResourceInterface resourceInterface;
...
}
I create the actual binding inside the languages RuntimeModule:
class MyRuntimeModule{
...
#Override
public void configure(Binder binder) {
super.configure(binder);
binder.bind(ExternalResourceInterface .class).to(ExternalResourceProductionAcess.class);
}
...
}
This works fine for the production environment.
However, in the generator test case, I would like to replace the binding with my mocked version, so that the following call to the CompilationTestHelper uses the mock:
compiler.assertCompilesTo(dsl, expectedJava);
Question:
Where do I tell guice/Xtext to bind the injection to the mock?
If you annotate your test case with RunWith and InjectWith, your test class will be injected via a specific IInjectorProvider implementation.
If that injector provider uses a custom module (like you have shown), the test case gets injected using that configuration. However, you have to make sure you use this injector throughout the test code (e.g. you do not rely on a registered injector, etc.).
Look for the following code as an example (have not compiled it, but this is the base structure you have to follow):
#RunWith(typeof(XtextRunner))
#InjectWith(typeof(LanguageInjectorProvider))
public class TestClass {
#Inject
CompilationTestHelper compiler
...
}
**I'm using PostSharp Express... not sure that would make a difference in this instance though.
I've got an OnMethodBoundary->OnEntry aspect that successfully multicasts at the assembly level to class members in my own code, but when I attempt to apply it to mscorlib System.IO.StreamReader members, no dice. Based on the searching I've done on the PostSharp web site, here on SO, and on Google, I can't tell what the correct way to go about this is with the current version of PostSharp. Does anyone know? Hopefully I'm just missing something simple :\
Here's the aspect followed by multicast attribute I'm using:
namespace Test.Aspects {
[AttributeUsage(AttributeTargets.Assembly)]
[MulticastAttributeUsage(MulticastTargets.Method, AllowMultiple = false)]
[Serializable]
public class PatchStreamReaderAttribute : OnMethodBoundaryAspect {
public override void OnEntry(MethodExecutionArgs args) {
System.Threading.Thread.Sleep(1000);
}
}
}
[assembly: PatchStreamReader(AttributeTargetMembers = "ReadLine", AttributeTargetAssemblies = "mscorlib", AttributeTargetTypes = "System.IO.StreamReader")]
Usually, when you apply an aspect in a given assembly, PostSharp will modify that assembly during its build process. This, of course, cannot happen for mscorlib or, in fact, for any 3-rd party library you reference but do not build from source code.
This is why PostSharp uses different approach when applying aspects to the referenced assemblies using AttributeTargetAssemblies. Instead of modifying the target 3-rd party assembly, PostSharp will modify the calls from your assembly to the target assembly.
This, of course, gives you less options of where you can inject your code. For example, PostSharp can detect the call to the library's method and inject the aspect around that call. But you cannot inject the aspect around the static or instance constructor of the type from the library.
You also need to pay attention to the AttributeTargetTypes property when applying the aspect. For example, you want to apply the aspect on the calls to the StreamReader.ReadLine() method. This virtual ReadLine() method is originally declared on the TextReader class and StreamReader overrides the method. If you look at the IL, then the method call looks like this:
callvirt instance string [mscorlib]System.IO.TextReader::ReadLine()
This means you need to set AttributeTargetTypes property to "System.IO.TextReader" to apply the aspect to the ReadLine() method.
I hope that someone can help me with this problem that I've been having with XmlSerializer.
I've already looked through this thread: http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/551cee76-fd80-48f8-ac6b-5c22c234fecf/
The error I am getting is:
System.InvalidOperationException: Unable to generate a temporary class (result=1).
error CS0012: The type 'System.Data.Objects.DataClasses.EntityObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
I've made sure that my unit test has a reference to System.Data.Entity, so it is able to compile at least. I've also in the app.config made an assembly binding to System.Data.Entity.
Here's my rough class structure
[Serializable]
[XmlRoot(Namespace = XmlSupport.MyNamespace, ElementName = XmlSupport.WantToSerialize)]
[XmlInclude(typeof(WantToSerializeBaseClass)]
[XmlInclude(typeof(EntityObject)]
[XmlInclude(typeof(MyEntityObjectSubClass)]
public class WantToSerialize : WantToSerializeBaseClass, IXmlSerializable (I've tried putting this on the baseclass and the current class)
{
// methods and classes
// I've included XmlIncludes for all the classes that this class has a reference too
// even though in the WriteXml it just uses .NET base classes
}
The WantToSerializeBaseClass makes use of some generics, but I've decorated it with XmlIncludes for (EntityObject, and any other classes it makes reference to as well).
the calling code:
var serializerWrite = new XmlSerializer(typeof (WantToSerialize), XmlSupport.ITNNamespace);
fails
However if I do:
var serializerWrite = new XmlSerializer(typeof (WantToSerialize), new Type[] {typeof(EntityObject)});
it is succesfull.
Any thoughts would be most helpful.
UPDATED
I've tracked the problem down to a method in the WantToSerializeBaseClass
public abstract void ConvertFromEntity<TtoCopy>(TtoCopy toCopy) where TtoCopy : MyEntityObjectSubClass;
Where MyEntityObjectSubClass is a subclass of EntityObject, that adds a few methods that I want on my entity objects. The MyEntityObjectSubClass looks like this:
[Serializable]
[XmlInclude(typeof(EntityObject))]
public abstract class MyEntityObjectSubClass : EntityObject, IMyEntityObjectSubClass
Again any thoughts would be great
If you don't have any code that requires a reference at compile time then that reference won't be included in the built assembly. You can use a tool like Reflector to check whether the reference is making it into your assembly.
One thing you can try is adding a static method to WantToSerialize that creates the XmlSerializer. The assembly containing WantToSerialize must already have a good reference to EntityObject, so this should solve the problem.
I have this same problem too (in VB). what I found is that you can use the generic parameter, but it errors because the type MyEntityObjectSubClass is in another assembly. If you remove the type restriction on the generic parameter it will work fine.
I believe this to be an error in the framework itself. I've submitted a feedback ticket to microsoft. I attached a VB.net
I ended up removing the generic code and it worked fine.
I realize this is an older question but for posterity's sake set the CopyLocal parameter on the .dll reference to True.
GWT.create() is the reflection equivalent in GWT,
But it take only class literals, not fully qualified String for the Class name.
How do i dynamically create classes with Strings using GWT.create()?
Its not possible according to many GWT forum posts but how is it being done in frameworks like Rocket-GWT (http://code.google.com/p/rocket-gwt/wiki/Ioc) and Gwittir (http://code.google.com/p/gwittir/wiki/Introspection)
It is possible, albeit tricky. Here are the gory details:
If you only think as GWT as a straight Java to JS, it would not work. However, if you consider Generators - Special classes with your GWT compiler Compiles and Executes during compilation, it is possible. Thus, you can generate java source while even compiling.
I had this need today - Our system deals with Dynamic resources off a Service, ending into a String and a need for a class. Here is the solutuion I've came up with - btw, it works under hosted, IE and Firefox.
Create a GWT Module declaring:
A source path
A Generator (which should be kept OUTSIDE the package of the GWT Module source path)
An interface replacement (it will inject the Generated class instead of the interface)
Inside that package, create a Marker interface (i call that Constructable). The Generator will lookup for that Marker
Create a base abstract class to hold that factory. I do this in order to ease on the generated source code
Declare that module inheriting on your Application.gwt.xml
Some notes:
Key to understanding is around the concept of generators;
In order to ease, the Abstract base class came in handy.
Also, understand that there is name mandling into the generated .js source and even the generated Java source
Remember the Generator outputs java files
GWT.create needs some reference to the .class file. Your generator output might do that, as long as it is referenced somehow from your application (check Application.gwt.xml inherits your module, which also replaces an interface with the generator your Application.gwt.xml declares)
Wrap the GWT.create call inside a factory method/singleton, and also under GWT.isClient()
It is a very good idea to also wrap your code-class-loading-calls around a GWT.runAsync, as it might need to trigger a module load. This is VERY important.
I hope to post the source code soon. Cross your fingers. :)
Brian,
The problem is GWT.create doen't know how to pick up the right implementation for your abstract class
I had the similar problem with the new GWT MVP coding style
( see GWT MVP documentation )
When I called:
ClientFactory clientFactory = GWT.create(ClientFactory.class);
I was getting the same error:
Deferred binding result type 'com.test.mywebapp.client.ClientFactory' should not be abstract
All I had to do was to go add the following lines to my MyWebapp.gwt.xml file:
<!-- Use ClientFactoryImpl by default -->
<replace-with class="com.test.mywebapp.client.ClientFactoryImpl">
<when-type-is class="com.test.mywebapp.client.ClientFactory"/>
</replace-with>
Then it works like a charm
I ran into this today and figured out a solution. The questioner is essentially wanting to write a method such as:
public <T extends MyInterface> T create(Class<T> clz) {
return (T)GWT.create(clz);
}
Here MyInterface is simply a marker interface to define the range of classes I want to be able to dynamically generate. If you try to code the above, you will get an error. The trick is to define an "instantiator" such as:
public interface Instantiator {
public <T extends MyInterface> T create(Class<T> clz);
}
Now define a GWT deferred binding generator that returns an instance of the above. In the generator, query the TypeOracle to get all types of MyInterface and generate implementations for them just as you would for any other type:
e.g:
public class InstantiatorGenerator extends Generator {
public String generate(...) {
TypeOracle typeOracle = context.getTypeOracle();
JClassType myTYpe= typeOracle.findType(MyInterface.class.getName());
JClassType[] types = typeOracle.getTypes();
List<JClassType> myInterfaceTypes = Collections.createArrayList();
// Collect all my interface types.
for (JClassType type : types) {
if (type.isInterface() != null && type.isAssignableTo(myType)
&& type.equals(myType) == false) {
myInterfaceTypes.add(type);
}
for (JClassType nestedType : type.getNestedTypes()) {
if (nestedType.isInterface() != null && nestedType.isAssignableTo(myType)
&& nestedType.equals(myTYpe) == false) {
myInterfaceTypes.add(nestedType);
}
}
}
for (JClassType jClassType : myInterfaceTypes) {
MyInterfaceGenerator generator = new MyInterfaceGenerator();
generator.generate(logger, context, jClassType.getQualifiedSourceName());
}
}
// Other instantiator generation code for if () else if () .. constructs as
// explained below.
}
The MyIntefaceGenerator class is just like any other deferred binding generator. Except you call it directly within the above generator instead of via GWT.create. Once the generation of all known sub-types of MyInterface is done (when generating sub-types of MyInterface in the generator, make sure to make the classname have a unique pattern, such as MyInterface.class.getName() + "_MySpecialImpl"), simply create the Instantiator by again iterating through all known subtypes of MyInterface and creating a bunch of
if (clz.getName().equals(MySpecialDerivativeOfMyInterface)) { return (T) new MySpecialDerivativeOfMyInterface_MySpecialImpl();}
style of code. Lastly throw an exception so you can return a value in all cases.
Now where you'd call GWT.create(clz); instead do the following:
private static final Instantiator instantiator = GWT.create(Instantiator.class);
...
return instantiator.create(clz);
Also note that in your GWT module xml, you'll only define a generator for Instantiator, not for MyInterface generators:
<generate-with class="package.rebind.InstantiatorGenerator">
<when-type-assignable class="package.impl.Instantiator" />
</generate-with>
Bingo!
What exactly is the question - i am guessing you wish to pass parameters in addition to the class literal to a generator.
As you probably already know the class literal passed to GWT.create() is mostly a selector so that GWT can pick and execute a generator which in the end spits out a class. The easist way to pass a parameter to the generator is to use annotations in an interface and pass the interface.class to GWT.create(). Note of course the interface/class must extend the class literal passed into GWT.create().
class Selector{
}
#Annotation("string parameter...")
class WithParameter extends Selector{}
Selector instance = GWT.create( WithParameter.class )
Everything is possible..although may be difficult or even useless. As Jan has mentioned you should use a generator to do that. Basically you can create your interface the generator code which takes that interface and compile at creation time and gives you back the instance. An example could be:
//A marker interface
public interface Instantiable {
}
//What you will put in GWT.create
public interface ReflectionService {
public Instantiable newInstance(String className);
}
//gwt.xml, basically when GWT.create finds reflectionservice, use reflection generator
<generate-with class="...ReflectionGenerator" >
<when-type-assignable class="...ReflectionService" />
</generate-with>
//In not a client package
public class ReflectionGenerator extends Generator{
...
}
//A class you may instantiate
public class foo implements Instantiable{
}
//And in this way
ReflectionService service = GWT.create(ReflectionService.class);
service.newInstance("foo");
All you need to know is how to do the generator. I may tell you that at the end what you do in the generator is to create Java code in this fashion:
if ("clase1".equals(className)) return new clase1();
else if ("clase2".equals(className)) return new clase2();
...
At the final I thought, common I can do that by hand in a kind of InstanceFactory...
Best Regards
I was able to do what I think you're trying to do which is load a class and bind it to an event dynamically; I used a Generator to dynamically link the class to the event. I don't recommend it but here's an example if it helps:
http://francisshanahan.com/index.php/2010/a-simple-gwt-generator-example/
Not having looked through the code of rocket/gwittir (which you ought to do if you want to find out how they did it, it is opensource after all), i can only guess that they employ deferred binding in such a way that during compile time, they work out all calls to reflection, and statically generate all the code required to implement those call. So during run-time, you cant do different ones.
What you're trying to do is not possible in GWT.
While GWT does a good job of emulating Java at compile time the runtime is of course completely different. Most reflection is unsupported and it is not possible to generate or dynamically load classes at runtime.
I had a brief look into code for Gwittir and I think they are doing their "reflection stuff" at compile time. Here: http://code.google.com/p/gwittir/source/browse/trunk/gwittir-core/src/main/java/com/totsp/gwittir/rebind/beans/IntrospectorGenerator.java
You might be able to avoid the whole issue by doing it on the server side. Say with a service
witch takes String and returns some sort of a serializable super type.
On the server side you can do
return (MySerializableType)Class.forName("className").newInstance();
Depending on your circumstances it might not be a big performance bottleneck.