How do I specify the factory Intellitest should use for an interface?

1.2k views Asked by At

With Intellitest you can specify a type for Intellitest to use that fits an interface when generating unit tests, however I have a custom factory I wish to use instead.

My custom factory:

public static partial class LogicFactory
{
    /// <summary>A factory for ILogic instances</summary>
    [PexFactoryMethod(typeof(ILogic))]
    public static ILogic Create(string defaultUICulture, bool saveSuccessful)
    {
        return Mock.Of<ILogic>(
        x =>
        x.GetUICulture(It.IsAny<string>()) == defaultUICulture &&
        x.Save(It.IsAny<string>(), It.IsAny<string>()) == saveSuccessful);
    }
}

I would like to use this factory for all ILogic instances PEX tries to create.

I tried adding the following attribute to PexAssemblyInfo.cs, and I also tried adding it above my test:

[assembly: PexCreatableByClassFactory(typeof(ILogic), typeof(LogicFactory))]

but I still get this runtime warning when instrumenting code:

will use Company.Logics.SpecificLogic as ILogic

And so it seems it's ignoring my factory every time. How can I force Intellitest to use my factory instead?

1

There are 1 answers

2
Michał Komorowski On BEST ANSWER

If you want to use PexCreatableByClassFactory you need a class that implements IPexClassFactory interface. Here is an example:

public partial class LogicFactory : IPexClassFactory<Logic>
{
    public Logic Create()
    {
        //...
    }
}

[assembly: PexCreatableByClassFactory(typeof(Logic), typeof(LogicFactory))]

It should be noted that IPexClassFactory works with concrete classes and not with interfaces. Now if Pex decides that an instance of Logic class should be created, the following code will be generated:

LogicFactory2 s2 = new LogicFactory();
Logic s1 = ((IPexClassFactory<Logic>)s2).Create();

If you prefer to use PexFactoryMethod it is also possible. However, PexFactoryMethod also works with concrete classes e.g.:

 [PexFactoryMethod(typeof(Logic))]
 public static Logic Create(string defaultUICulture, bool saveSuccessful)
 {
      //...
 }

If you use both solutions at the same time i.e. define a pex factory method and a pex factory class for the same type, then according to my experience a pex factory method will have a higher priority.

If you have more than one class that implements ILogic interface you need to defined a pex factory method and/or a pex factory class for each of these classes. Otherwise PEX will try to create instances of these classes on his own.

If you want to get rid of mentioned warning right click it and select Fix from a context menu. Pex will generate the following attribute for you:

[assembly: PexUseType(typeof(SpecificLogic))]