1

I use static variables in the beginning of code file because I use it later for verifying values:

static string fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(Data["FirstName"] ));

public void FillName()    {
  Pages.SitecoreCMS.Field_Company.Text = fullNameValue;
}

// break.............

public void VerifyingFullName()    {
  Assert.IsTrue(ArtOfTest.Common.CompareUtils.StringCompare(Pages.Contact.FrameContentIFrame.SitecoreTentativeaccountnameText.Text,fullNameValue, ArtOfTest.Common.StringCompareType.Contains));
}

Compilation is failed: An object reference is required for the non-static field, method, or property 'ArtOfTest.WebAii.Design.BaseWebAiiTest.Data.get'

How I should change this code? I used non static variables before, but I can't to use it by another methods (e.g. VerifyingFullName).

algot
  • 2,428
  • 3
  • 19
  • 23

3 Answers3

2

As the error says: your Data property is non-static. Make it static to access it in a static context.

However, since your code snippet only references the fullNameValue field in a non-static context you could probably declare fullNameValue as an instance variable and your code would be fine.

Rich O'Kelly
  • 41,274
  • 9
  • 83
  • 114
1

You have to also have the Data variable as static. You are declaring fullNameValue as static, which means you are in a static context and therefore cannot use instance variables, since static is not associated to any instance of the class.

Tudor
  • 61,523
  • 12
  • 102
  • 142
1

Well, you could modify your fullNameValue field to be the following code, instead. I think this would resolve your error.

The issue seems to be that your initialization code for your fullNameValue field is referencing the Data property (Data["FirstName"]), but Data is an instance property, not a static property, therefore you can't reference it in a static context (i.e. when initializing a static field).

    static object _syncLock = new object();
    static string _fullNameValue;

    string fullNameValue
    {
        get
        {
            lock (_syncLock)
            {
                if (_fullNameValue == null)
                {
                    _fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(Data["FirstName"]));
                }
                return _fullNameValue;
            }
        }
    }

It looks like you're using this for unit testing purposes. In that case, it looks to me like this code will generate a single value for fullNameValue and will reuse that for all test cases.

If that's what you want, then this would be ok. However, my guess is that you may find that this code behaves incorrectly if you start to use different test data for different tests, although I'm not familiar with the ArtOfTest framework. If this gives you trouble, then you might want to reconsider whether the _fullNameValue field should be static.


Alternatively, as discussed in the comments, you could make the fullNameValue field to be non-static, and then initialize it in the constructor. Below is the code:

    string fullNameValue;
    string companyValue;

    public PricingForm()
    {
        fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(Data["FirstName"]));
        companyValue = // code to initialize company value
    }


Yet another alternative: you might want to try converting the fullNameValue field to a property. Again, this may produce different behavior than the examples above. Does each call to GenerateUniqueId return a different value, even if the input parameter is the same? Then that means each time that you access this property you will get a different value back, so consider whether this is what you want.
    string fullNameValue
    {
        get { return UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(this.Data["FirstName"])); }
    }


In light of the discussion in the comments, my suggestion is to use the approach shown below.

This performs lazy initialization of the _fullNameValue field (which appears to be necessary because the BaseWebAiiTest class' Data property is not initialized at the time that the constructor executes). I've left out the locking code because it may not be necessary and the OP expressed concerns about the verbosity of it.

string _fullNameValue;

string fullNameValue
{
    get
    {
        if (_fullNameValue == null)
            _fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(this.Data["FirstName"]));

        return _fullNameValue;
    }
}
Dr. Wily's Apprentice
  • 10,212
  • 1
  • 25
  • 27
  • Maybe I could not use static variables? public class PricingForm : BaseWebAiiTest` { string fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(Data["FirstName"])); public void FillFullName() { // Enter text in 'Field_FullName' Pages.SitecoreCMS.Field_FullName.Text = this.fullNameValue; } } – algot Jan 04 '12 at 15:06
  • @algot - Yep, that would work as well. The behavior would be slightly different (each instance of your PricingForm class would have it's own unique value for fullNameValue instead of all instances having the same value), but that may be what you want. – Dr. Wily's Apprentice Jan 04 '12 at 15:09
  • I change code that way, but error still occurs. **An object reference is required for the non-static field** – algot Jan 04 '12 at 15:13
  • @algot - ah, sorry. You could try assigning the value to fullNameValue in the constructor instead. I'll update my answer with code for that. – Dr. Wily's Apprentice Jan 04 '12 at 15:20
  • I use this variable for one test. So I don't need to reuse it in different tests. Your code is working but what should I do if I need to determine several variables? Write such code again for each one? o_O – algot Jan 04 '12 at 15:35
  • @algot - Well, if you need to prepare other variables for other tests, then I would add those as additional member variables (fields) of your PricingForm class and would initialize them similarly. You seem concerned about code duplication, no? Without having a better understanding, I can't really give a good suggestion for how to reduce code duplication for test data initialization logic. – Dr. Wily's Apprentice Jan 04 '12 at 15:49
  • I mean that I have several fields - fullNameValue/companyValue etc. Should I write all that code you wrote for each of them? – algot Jan 04 '12 at 15:54
  • @algot - I would prefer to use the non-static field approach described in the second code sample in my answer (I've updated it to include a companyValue field). The first code sample is a typical approach to lazy instantiation of a static variable, and I doubt that it is necessary or useful in a unit testing scenario. – Dr. Wily's Apprentice Jan 04 '12 at 16:03
  • Your code doesn't work :( Following error occurs: '1/4/2012 6:07:42 PM' - System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object. at Portal_CRM.PricingForm..ctor() in C:\Users\ago.DK\Documents\Test Studio Projects\Portal_CRM\PricingForm.tstest.cs:line 97 --- End of inner exception stack trace --- – algot Jan 04 '12 at 16:09
  • @algot - Ok, my guess is that the Data property of your BaseWebAiiTest class may not be initialized yet, so accessing it inside of the constructor may not be valid. The error indicates that something (probably the Data property) is null, so you could set a breakpoint and look at the values of objects in your code to figure out where your problem is. – Dr. Wily's Apprentice Jan 04 '12 at 16:24
  • Yes, Data is null on this step. – algot Jan 04 '12 at 16:33
  • @algot - Ok, then I think you'll probably need to refer to documentation or examples that are specific to the ArtOfTest framework in order to know exactly when/how you should be using the Data property on the BaseWebAiiTest class. I did update my answer with one more code sample where I converted the fullNameValue field into a property instead. This approach does not require you to initialize the value in the constructor, because the value is derived whenever you get the value from this property. I don't know if that will provide the behavior that you want, but it may work for you. – Dr. Wily's Apprentice Jan 04 '12 at 16:51
  • Code is working but if I check values of variables value generates again, so it is not equal to initial value. – algot Jan 05 '12 at 10:07
  • @algot - Updated my answer with another suggestion at the end. This will ensure that the value of the fullNameValue property is the same each time you access it. – Dr. Wily's Apprentice Jan 05 '12 at 14:09