How do I get a custom element definition without instantiating it? - unit-testing

After looking at the custom element spec, it's not immediately obvious how I get a reference to a custom element definition without first instantiating it (which can be problematic). Is there a way to directly reference a custom element's prototype?
More concretely, if I have:
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function() { // some heavy operation };
document.registerElement('x-foo', {prototype: proto});
At some point later, I would love to reference the prototype with something like:
// wish
var XFoo = document.getElementDefinition('x-foo');
But instead the only way I've come up with is:
// reality
var XFoo = document.createElement('x-foo').__proto__;
This is especially problematic when trying to write tests against heavy components - as there's no way to stub out the heavy behavior (with something like XFoo.createdCallback = // stub; before the original method is actually called.

If you have reference to the constructor of the custom element, you can use it to access the prototype.
var XFoo = document.registerElement('x-foo', {prototype: proto});
XFoo.prototype // this will give u access to the prototype object.

there's no way to stub out the heavy behavior
Use a function reference rather than an anonymous function:
proto.createdCallback = model.foo;
define it:
var model = {};
model.foo = function(){/*some heavy operation*/};
then stub it by redefining it:
var XModel = {};
XModel.foo = function(){/*stub*/};
and reference it in the test:
XFoo.createdCallback = XModel.foo;
References
AOP Aspect of JavaScript
AJAX Interception
Intro to Aspect Oriented Programming

Related

Getting values from THIS scope after init function (persistency inside CFC)

I'm initiating a CFC like this.
<cfscript>
lock scope="application" timeout="5" {
application.mycfc = new mycfc();
}
writeOutput(application.mycfc.readVars());
</cfscript>
In the CFC, I'm setting some properties.
component output="false" accessors="true" {
property name="title";
property name="foo";
this.title = "mycfc";
function init() {
this.foo = "bar";
// I can now properly read this.title, or this.foo.
return this;
}
function readVars() {
// Here, I can read this.title, from the constructor space, but I can't
// read this.foo. It's just blank (because the default value of the
// `default` attribute of `property` is "")
}
}
Because of the implementation (caching in Application), I can instead use application.mycfc.foo in readVars().
Because of this name, it's hard to Google for details. I thought it would be persistent throughout the CFC's life, but apparently it is not?
I surely could do something like
var self = application[this.title]; // or application.mycfc
Or perhaps even
this = application[this.title];
In functions where I want to get/set without typing application.mycfc each time.
Just trying to make sure I'm not doing something wrong, or reinventing the wheel.
In my real implementation, I'm pulling from rows from a database to populate a struct.
Scopes in ColdFusion components (.cfc):
this
is the public scope, read/write from anywhere
properties
is a magical scope, read/write only via accessors (a.k.a. getters/setters) from anywhere
variables
is the private scope, read/write only within your component
All of these scopes can coexist, but this.x is NOT the same field as property name="x"!
Since you are using a component with accessors="true", all your property fields can only be read via getter and written via setter. So if you want to write your title property, use setTitle("mycfc"); instead of this.title = "mycfc";. Same goes for the foo property. Use setFoo("bar"); instead of this.foo = "bar";. If you want to read the properties, use application.mycfc.getTitle() and application.mycfc.getFoo(). If you want to set properties at runtime, use application.mycfc.setTitle("something"). Note that writing to a shared scope such as application should happen in a cflock to avoid race conditions (thread-safety).
If you don't need accessors at all, you can simply use public fields instead (accessors is missing here, i.e. set to false):
component output="false" {
this.title = "mycfc";
this.foo = "";
function init() {
this.foo = "bar";
return this;
}
function readVars() {
return this;
}
}
application.mycfc = new mycfc();
writeOutput(application.mycfc.title); // mycfc
writeOutput(application.mycfc.foo); // bar
application.mycfc.title = "something";
writeOutput(application.mycfc.title); // something
writeOutput(application.mycfc.foo); // bar
Public fields are usually not recommended though as they break encapsulation.

How to check any of multiple overloads called NSubstitute

Scenario
I would like to check if a component (the sut) logs error in a particular condition. The ILogger interface constructor injected into the component, and the Error method has 4 overloads.
So I create a ILogger mock in the Arrange and using it in the Act.
I should not expect which overload the sut is using, just would like to expect and check if any of the overload called. (that would extremely white-box, and expects far more than the functional spec.)
Question
Currently my conclusion is that I can not utilize the .Received instead I must install callbacks for all the 4 overloads, and set a variable inside them, and in the Assert part I examine that variable.
Is any simple way to do this what I missed?
(example)
[TestMethod]
public void ShouldLogErrorIfEmailIsInvalid2()
{
// Arrange
var testEmailAddress = "dummy";
//var mock = new Mock<IEMailValidator>();
var validator = Substitute.For<IEMailValidator>();
validator.Validate(Arg.Any<string>()).Returns(false);
var logger = Substitute.For<ILogger>();
var sut = new CustomerController(validator, logger);
var customer = new Customer() { Email = testEmailAddress };
// Act
sut.Post(customer);
// Assert
// *** Here I do not want to expect a specific overload of Error, instead any of the 4 overloads satisfies the expectation
logger.Received(1).Error(Arg.Is<string>( m => m.ToLower().Contains("email")), Arg.Any<object>());
}
NSubstitute does not have built-in syntax for this, but it is possible to query all ReceivedCalls() and manually assert on this.
For example:
var errorCalls = logger.ReceivedCalls()
.Where(x => x.GetMethodInfo().Name == nameof(logger.Error))
.Where(x => (x.GetArguments()[0] as string).ToLower().Contains("email"));
Assert.AreEqual(1, errorCalls.Count());
If this this is something you need frequently you could implement some helper methods and package this up into something fairly concise I think. (Maybe static void ReceivedCallToAny(this object substitute, string methodName, Func<object[], bool> requiredArgs) with some helpers like T GetItemAs<T>(object[] items) to access arguments?)

How to create Single.just(Void)

I am writing some unit test cases for my application. I want to mock MongoClient update method, but the update returns Single<Void>.
when(mongoClient.rxUpdate(anyString(), any(JsonObject.class), any(JsonObject.class)))
.thenReturn(Single.just(Void))
Now Single.just(Void) doesn't work, what is the correct way of doing it?
--UPDATE--
So I am writing unit test for updateUserProfile method and for that I have mocked service. But the service.updateAccount method return is something I am not able to mock.
//Controller class
public void updateUserProfile(RoutingContext routingContext){
// some code
service.updateAccount(query, update)
.subscribe(r -> routingContext.response().end());
}
//Service Class
public Single<Void> updateAccount(JsonObject query, JsonObject update){
return mongoClient.rxUpdate("accounts", query, update);
}
Because the return type of mongoClient.rxUpdate is Single<Void>, I am not able to mock that part.
For now the workaround which I have figured out is:
public Single<Boolean> updateAccount(JsonObject query, JsonObject update){
return mongoClient.rxUpdate("accounts", query, update).map(_void -> true);
}
But this is just a hacky way of doing it, I want to know how can I exactly create Single<Void>
Having a method returning Single<Void> may raise some concerns, as some users have already expressed their view on this in the comments.
But if you are stuck with this and you really need to mock it (for whatever reason), there are definitely ways to create a Single<Void> instance, for example you could use the create method of the Single class:
Single<Void> singleVoid = Single.create(singleSubscriber -> {});
when(test.updateAccount(any(JsonObject.class), any(JsonObject.class))).thenReturn(singleVoid);
Single<Void> result = test.updateAccount(null, null);
result.subscribe(
aVoid -> System.out.println("incoming!") // This won't be executed.
);
Please note: you won't be able to actually emmit a Single item, since Void can't be instantiated without reflection.
A trick that could eventually work in some cases is to ommit the generic type argument and emmit an Object instead, but this could lead easily to a ClassCastException. I would not recommend to use this:
Single singleObject = Single.just(new Object());
when(test.updateAccount(any(JsonObject.class), any(JsonObject.class))).thenReturn(singleObject);
Single<Void> result = test.updateAccount(null, null);
// This is going to throw an exception:
// "java.base/java.lang.Object cannot be cast to java.base/java.lang.Void"
result.subscribe(
aVoid -> System.out.println("incoming:" + aVoid)
);
And of course you could use reflection as well (as already suggested by Minato Namikaze):
Constructor<Void> constructor = Void.class.getDeclaredConstructor(new Class[0]);
constructor.setAccessible(true);
Void instance = constructor.newInstance();
Single<Void> singleVoidMock = Single.just(instance);
when(test.updateAccount(any(JsonObject.class), any(JsonObject.class))).thenReturn(singleVoidMock);
Single<Void> result = test.updateAccount(null, null);
result.subscribe(
aVoid -> System.out.println("incoming:" + aVoid) // Prints: "incoming:java.lang.Void#4fb3ee4e"
);

How to override KeyValuePair<TKey, TValue> in C#?

I want to override the default structure of KeyValuePair in C#, so that I can make a KeyValuePair to accept a 'var' types.
Something like this :
List<KeyValuePair<string, var>> kvpList = new List<KeyValuePair<string, var>>()
{
new KeyValuePair<string, var>("Key1", 000),
new KeyValuePair<string, var>("Key2", "value2"),
new KeyValuePair<string, var>("Key3", 25.45),
};
Even if its possible for dictionary, then also it will solve my problem.
You could use object as your type, and then cast to/from object to desired outcomes. However, it's important to note that this is very much the opposite of object oriented programming, and generally indicates an error in your design and architecture.
Hmm I am wondering if this might help you: To have a list as you want, it is really possible BUT the "var" type (as you named it) must be the same for all KeyValuePair instances. For having whatever type you must use object or dynamic (use Haney's answer).
So considering that you want a single type for all KeyValuePair instances, here is a solution:
Firstly, create this helper class:
public static class KeyValuePairExtentions
{
public static List<KeyValuePair<string, T>> GetNewListOfType<T>(Expression<Func<T>> type)
{
return new List<KeyValuePair<string, T>>();
}
public static void AddNewKeyValuePair<T>(this List<KeyValuePair<string, T>> #this, string key, T element)
{
#this.Add(new KeyValuePair<string, T>(key, element));
}
}
To consume these functions, here is an example:
var lst = KeyValuePairExtentions.GetNewListOfType(() => new {Id = default (int), Name = default (string)});
lst.AddNewKeyValuePair("test1", new {Id = 3, Name = "Keith"});
The ideea is to rely on the powerfull type inference feature that we have in C#.
Some notes:
1) if T is anonymous and you create a new instance of a list in an assembly and consume it in another assembly it is VERY possible that this will NOT work due to the fact that an anonymous type is compiled per assembly (in other words, if you have a variable var x = new { X = 3 } in an assembly and in another var y = new { X = 3 } then x.GetType () != y.GeTType () but in the same assembly types are the same.)
2) If you are wondering whether an instance it's created or not by calling GetNewListOfType, the answer is NO because it is an expression tree function and the function is not even compiled. Even with a Func will work because I am not calling the function in my code. I am using the function just for type inference.

Should I duplicate test data and assert data?

The question is probably best asked with a simple example:
var myObj = { name: 'John' };
var copiedObj = ObjectCopier.copy(myObj);
copiedObj.name.should.equal('John'); // Hard code 'John' twice
copiedObj.name.should.equal(myObj.name); // Reference the original value
Is one method preferred over the other? Assuming the value passed in is what I expect to be returned, is there any harm in the 2nd assert? Does it even matter?
In more complex cases you won't be able to duplicate an object completely - and you wouldn't want to. it would be better written this way:
var OBJ_NAME = 'John'
var myObj = { name: OBJ_NAME };
var copiedObj = ObjectCopier.copy(myObj);
copiedObj.name.should.equal(OBJ_NAME);
this way you're not duplicating any code/defines, and you can also make tests such as:
myObj.name.should.equal(OBJ_NAME);
to test for the object copier not changing the original object either (which either of your lines won't test for).