To illustrate what Keith mentioned in his comment, try running your above code in the execute anonymous window. Using a checkbox field on Account, I simulated what you are trying to do, with and without casting as Keith mentioned and with casting it definitely should work as you believe it should.
Account acctTrue = [select Match_Billing_Address__c from Account WHERE Match_Billing_Address__c = true limit 1];
Account acctFalse = [select Match_Billing_Address__c from Account WHERE Match_Billing_Address__c = false limit 1];
Boolean x1 = acctTrue.Match_Billing_Address__c; // => true
Boolean x2 = acctTrue.get('Match_Billing_Address__c'); // => null
Boolean x3 = acctFalse.Match_Billing_Address__c; // => true
Boolean x4 = acctFalse.get('Match_Billing_Address__c'); // => null
System.assertEquals(x1, x2);
System.assertEquals(x3, x4);
System.debug('x1:' + x1 + ' x2:' + x2 + ' x3:' + x3 + ' x4:' + x4);
The above results in the error when attempted to run:
However, after adding boolean casts to both lines 4 and 6:
Account acctTrue = [select Match_Billing_Address__c from Account WHERE Match_Billing_Address__c = true limit 1];
Account acctFalse = [select Match_Billing_Address__c from Account WHERE Match_Billing_Address__c = false limit 1];
Boolean x1 = acctTrue.Match_Billing_Address__c; // => true
Boolean x2 = (Boolean)acctTrue.get('Match_Billing_Address__c'); // => null
Boolean x3 = acctFalse.Match_Billing_Address__c; // => true
Boolean x4 = (Boolean)acctFalse.get('Match_Billing_Address__c'); // => null
System.assertEquals(x1, x2);
System.assertEquals(x3, x4);
System.debug('x1:' + x1 + ' x2:' + x2 + ' x3:' + x3 + ' x4:' + x4);
You can see the results in the debug log and the asserts passed.
Update based on the comment, I believe what you need to do in your test class is load the defaults for the field, the following from the docs, should help you resolve that issue:
newSObject(recordTypeId, loadDefaults)
Constructs a new sObject of this type, and optionally, of the specified record type ID and with default custom field values.
Signature
public sObject newSObject(ID recordTypeId, Boolean loadDefaults)
Parameters
recordTypeId
Type: ID
Specifies the record type ID of the sObject to create. If no record
type exists for this sObject, use null. If the sObject has record
types and you specify null, the default record type is used.
loadDefaults
Type: Boolean
Specifies whether to populate custom fields with their predefined
default values (true) or not (false).
Return Value
Type: sObject
Usage
For required fields that have no default values, make sure to provide
a value before inserting the new sObject. Otherwise, the insertion
results in an error. An example is the Account Name field or a
master-detail relationship field.
Since picklists and multi-select picklists can have default values
specified per record type, this method populates the default value
corresponding to the record type specified.
If fields have no predefined default values and the loadDefaults
argument is true, this method creates the sObject with field values of
null.
If the loadDefaults argument is false, this method creates the sObject
with field values of null.
This method populates read-only custom fields of the new sObject with
default values. You can then insert the new sObject with the read-only
fields, even though these fields cannot be edited after they’re
inserted.
If a custom field is marked as unique and also provides a default
value, inserting more than one new sObject will cause a run-time
exception because of duplicate field values.
get
method will return the same value or throw an "Invalid field" exception if the name is wrong. AsBoolean x2 = obj.get('check_Boolean__c');
won't compile unless you include a Boolean cast, I suspect you may be reaching the wrong conclusion in your testing.