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

1

8

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?

Hemotherapy answered 24/2, 2016 at 14:38 Comment(0)
C
3

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))]
Coonhound answered 4/3, 2016 at 10:8 Comment(2)
So you're saying it isn't possible to tell PEX to use a factory for an interface without specifying a concrete type?Hemotherapy
I'm not aware of this kind of possibility. However, I have to admit that I'm quite fresh with PEX.Jyoti

© 2022 - 2024 — McMap. All rights reserved.