简体   繁体   中英

Nsubstitute: Received checks wrong method

I have a test, where NSubstitute checks the wrong call at a fake class. When I do the test like the following code, the Received(...) method checks, that the value factory.featureClassName is returned once.

[Test]
public void CreateDataController_WhenCalled_CreatesServiceSettings()
{
    var factory = Substitute.ForPartsOf<AbstractDataServiceFactoryFake>("fileName");

    factory.CreateDataController();

    factory.Received(1).CreateServiceSettings("fileName", factory.FeatureClassName);
}

To test (like intended) that the method CreateServiceSettings(...) is called once I have to use the following code:

[Test]
public void CreateDataController_WhenCalled_CreatesServiceSettings()
{
    var factory = Substitute.ForPartsOf<AbstractDataServiceFactoryFake>("fileName");
    var featureClassName = factory.FeatureClassName;

    factory.CreateDataController();

    factory.Received(1).CreateServiceSettings("fileName", featureClassName);
}

It seems, that the Recieved() method is not directly connected to the method given after the call. Can anybody explain me, why this is happening?

This is a limitation of NSubstitute's syntax.

Let's break down what happens with the second code sample:

factory
    .Received(1)    // ... check the next call has previously been received
    .CreateServiceSettings("fileName", className) 
                    // call is made to CreateServiceSettings, NSub checks
                    // it was received.

In the first code sample, we get this instead:

factory
    .Received(1)    // ... check the next call has previously been received
    .CreateServiceSettings("fileName", factory.FeatureClassName) 
                    // before CreateServiceSettings is invoked, its arguments
                    // must be evaluated. So factory.FeatureClassName
                    // is called next and NSubstitute checks that.

In other words, NSubstitute sees the second code sample like this:

var _ = factory.Received(1).FeatureClassName;
factory.CreateServiceSettings("fileName", _);

To avoid this it is useful to avoid calling back into a substitute during an assertion (like Received ) or configuration (like Returns ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM