DevLabs > DevLabs Forums > Pex > Pex does not use my factory method
Ask a questionAsk a question
 

AnswerPex does not use my factory method

  • Tuesday, September 29, 2009 1:22 PMSwaroop Ganaganoor Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi,

    I've been writing PUTs for a program on shopping carts. Basically, a ShoppingCart object can hold many Product objects. 

    Class Product
    {
      int price;
      String productName;
    }

    To write test cases, I need shopping carts that are filled with different products and of different sizes based on my PexAssume statement.

    Problem: 
    I'm using the following function parameters for one of my PUTs:

    public void TestRemoveItemPUTSpecificCase([PexAssumeUnderTest]ShoppingCart target, Product item)

    I have factory methods for ShoppingCart as well as Product - ShoppingCartFactory and ProductFactory respectively. Something weird happens here.Pex uses my ShoppingCartFactory. However,although I have a factory class for Product, Pex sees that it can create the product object without any help and tries to generate a product (Without calling my factory). If Pex sees that it can generate an object, it never uses my factory class. I found some similar behavior here:

    http://social.msdn.microsoft.com/Forums/en/pex/thread/4b7c1f26-9846-4604-8119-0af59107fe26

    In such cases, how can I force Pex to use my factory methods?
    •  

Answers

  • Tuesday, September 29, 2009 10:00 PMNikolai TillmannMSFT, OwnerUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    > However,although I have a factory class for Product, Pex sees that it can create the product object without any help and tries to generate a product (Without calling my factory).


    You are right, if Pex can figure out how to create arbitrary instances of a class, Pex won't use your factory method.
    Just to make sure we are all on the same page: Your class either has only public fields, or there is a simple way how to set all fields via a constructor or setter methods?

    > In such cases, how can I force Pex to use my factory methods?

    Easy: Just add a non-public (e.g. "private") dummy field to your class; a field that is not used (get or set) by any method. Then it will be impossible for Pex to figure out how to configure the object in all possible ways, and Pex will rely on your factory method.

    Nikolai Tillmann - Tell us how you use Pex

All Replies

  • Tuesday, September 29, 2009 10:00 PMNikolai TillmannMSFT, OwnerUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    > However,although I have a factory class for Product, Pex sees that it can create the product object without any help and tries to generate a product (Without calling my factory).


    You are right, if Pex can figure out how to create arbitrary instances of a class, Pex won't use your factory method.
    Just to make sure we are all on the same page: Your class either has only public fields, or there is a simple way how to set all fields via a constructor or setter methods?

    > In such cases, how can I force Pex to use my factory methods?

    Easy: Just add a non-public (e.g. "private") dummy field to your class; a field that is not used (get or set) by any method. Then it will be impossible for Pex to figure out how to configure the object in all possible ways, and Pex will rely on your factory method.

    Nikolai Tillmann - Tell us how you use Pex
  • Thursday, October 29, 2009 7:04 PMxor88 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Can we turn this behavior off? I think it is quite common to have a factory for a type that could be initialized by pex without any help. In this case i would want the factory to have priority (if not, i would not have created it).
  • Thursday, October 29, 2009 8:27 PMNikolai TillmannMSFT, OwnerUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    OK, I can certainly see that when you go through the effort of writing a factory method, then you want it to be used.
    I made the change you requested: The next Pex version will always use the factory method.

    In any case, I am curious. Can you give me an example where you don't want that Pex creates an object automatically?

    Thanks

    Nikolai Tillmann - Tell us how you use Pex
  • Friday, October 30, 2009 1:25 PMxor88 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Wow, thanks.

    Reasons for not auto-creating an object:
    • performance (for example the class has 50 properties but only 5 are interesting to this test. i have sent a repro to the pex team a few days ago regarding a perf problem that was caused by to many irrelevant properties)
    • avoiding side-effects caused by a setter or constructor
    • an object may get into an illegal state if all properties can assume all possible values of their domain (for example a PositivePoint would be made negative by pex. instead of allways assuming p.X >= 0 the factory assumes it once)