chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hello,

I have a class that looks like:

public class A
{
private BCollection _bobjects = null;

private BCollection BObjects
{
get
{
if (_bojects == null)
_bobjects = new BCollection();
return _bobjects;
}
}

public static A GetInstance()
{
A a = new A();
//Set any properties

return a;
}

public void RegisterB(B b)
{
if (b == null)
throw new ArgumentNullException("b");

this.BObjects.Add(b);
}
}

OK, so the things I want to test are:

- GetInstance - I want to verify the inner method/properties calls after the class A is instantiated, using Isolate.Verify.
- I want to test that the Add method has been called in RegisterB, to ensure the object is being added to the collection, using the Isolate object.

How do I do this in the new Arrange/Act/Assert pattern through the Isolate static object?

Thanks.[/list]
asked by bmains (13.2k points)

8 Answers

0 votes
Hi,

To answer the first question you have to handle a future instance of A - this is done using the Swap.NextInstance() entry point, and will cause the new 'A' to be swapped with the fake instance we can verify against
[TestMethod]
public void GetInstance_SetPropertyOnNewInstance_PropertySetterIsCalled()
{
    // arrange - create a fake A to replace the A instantiation
    var fakeA = Isolate.Fake.Instance<A>();
    Isolate.Swap.NextInstance<A>().With(fakeA);

    // act
    var realA = A.GetInstance();

    //assert - I invented a property to verify on
    Isolate.Verify.WasCalledWithExactArguments(() => { fakeA.Prop = 5; });
}


The second question requires us to verify on a private property getter (BObjects). We do that by using the NonPublic API and inject a fake BCollection that replaces BObjects, and verify against that.

[TestMethod]
public void RegisterB_AddingToCollection_ObjectIsAdded()
{
    // arrange
    var fakeBObjects = Isolate.Fake.Instance<BCollection>();
    Isolate.WhenCalled(() => fakeBObjects.Add(null)).IgnoreCall();

    var fakeA = Isolate.Fake.Instance<A>(Members.CallOriginal);
    Isolate.NonPublic.Property.WhenGetCalled(fakeA, "BObjects").WillReturn(fakeBObjects);

    // act
    var b = new B();
    fakeA.RegisterB(b);

    // assert
    Isolate.Verify.WasCalledWithExactArguments(() => fakeBObjects.Add(b));
}



Please let me know if this helps.

Doron
Typemock Support
[/code]
answered by doron (17.2k points)
0 votes
That does help, thanks.
answered by bmains (13.2k points)
0 votes
Another question: if in that static method in A, I pull information from a custom configuration section that does something like:

public static A GetInstance()
{
A a = new A();

var cfg = MyCustomConfigSection.Instance;
//Load config settings into a

return a;
}

Would you recommend mocking the static property Instance (which returns an instance of a custom config component that retrieves it via ConfigurationManager.GetSection), or would you recommend mocking GetInstance and return a custom fake object?

From an ease of use and performance related.

THanks.
answered by bmains (13.2k points)
0 votes
Hi Brian,

I wrote about it in the Typemock insiders blog:http://blog.typemock.com/2009/05/quick-tip-how-to-fake-singleton.html

I don't think it matters which of the two you choose as long as they work (faking the instance can only be done before it created).

BTW
In the next version of Typemock Isolator a new feature will be added to enable you to fake all instances (even ones that were already created) which you can use as well.

Dror
Typemock Support
answered by dhelper (11.9k points)
0 votes
I'm noticing that this:

Isolate.WhenCalled(() => fakeBObjects.Add(null)).IgnoreCall();

If the collection method Add validates the input, this is generating an exception. Is that supposed to happen?

Also, you follow up with, in your test:

Isolate.Verify.WasCalledWithExactArguments(() => fakeBObjects.Add(b));

For me, I get an error that Add wasn't called, and I suspect that's because of the IgnoreCall method.

Has anyone experienced this?

Thanks.
answered by bmains (13.2k points)
0 votes
:?: I'm not sure this is so, but is there a chance that fakeBObjects is a standart collection? (i.e. one which is implemented in mscrolib)

If that is the case than you should be aware that at this point Isolator does not deal with types in MSCorlib (other than DateTime see the latest version).

In general, mocking a method means that the real call will not be executed, so you shouldn't see any exception generated by the "Add" real implementation.
answered by error (6.6k points)
0 votes
Hello,

No, its a custom collection not in MSCoreLib, its my own collection. The mock I'm doing is:

var collectionFake = Isolate.Fake.Instance<PropertyCollection>();
Isolate.SwapNextInstance<PropertyCollection>();
Isolate.WhenCalled(() => collectionFake.Add(new Property("test", this))).IgnoreCall();

var propertyFake = Isolate.Fake.Instance<Property>();
var m = new ModTest();

Isolate.WhenCalled(() => m.AddProperty(null)).IgnoreCall();

m.AddProperty(propertyFake);

Isolate.Verify.WasCalledWithExactArguments(() => collectionFake.Add(propertyFake));

PropertyCollection inherits from a custom colleciton class; that custom collection uses the generic list internally, but it does not inherit directly, but simply defines its own methods. That shouldn't be the issue; besides, I think MSCorLib entities throws exceptions.

But this doesn't work, and as far as I can tell, this is similar to the setup I asked about. Any help as to why verify doesn't verify the add call?

Thanks.
answered by bmains (13.2k points)
0 votes
Hi,
What error (or Lior) meant was that even for custom collections, that are not defined in mscorlib, but are based on the collections from mscorlib Isolator has a limitation with them.

The problem is that the Add method, unless you give it a custom implementation, is defined in mscorlib, and that's why setting behavior on it is not possible.

I'm not however understand the problem completely, and would like to take a look at the entire code. Since you have multiple questions around the same code, let's take it offline. I'll write you a separate email.

Thanks,
answered by gilz (14.5k points)
...