Pex does not use my factory method
- 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-0af59107fe26In such cases, how can I force Pex to use my factory methods?
Answers
- > 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- Marked As Answer byNikolai TillmannMSFT, OwnerTuesday, October 27, 2009 1:38 PM
- Proposed As Answer byNikolai TillmannMSFT, OwnerWednesday, September 30, 2009 5:45 PM
All Replies
- > 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- Marked As Answer byNikolai TillmannMSFT, OwnerTuesday, October 27, 2009 1:38 PM
- Proposed As Answer byNikolai TillmannMSFT, OwnerWednesday, September 30, 2009 5:45 PM
- 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).
- 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 - 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)


