I've been working on a unit test with angular.mock.$httpBackend for an angular service that uses $http. I'm running into some issues related to injecting all the dependencies, because my test case needs to access the service, which in turn needs to access $httpBackend.
However, the specific issue that is tripping me up now is that sometimes the angular.mock.inject() convenience method executes the function it wraps immediately, and sometimes it just returns a copy of the function. I see in the source that this is based on a property called currentSpec.isRunning. What does this mean? Is this a Testacular or Jasmine property? I haven't gone that far down the rabbit hole yet...
Last I checked, the return value of angular.mock.inject() was based upon what type of Jasmine context you are in (I'm assuming they changed it up a bit in 1.2 with the addition of mocha support).
Essentially, if your in a spec (actually inside of a callback passed to beforeEach):
beforeEach(function () {
inject(function () { });
});
Then it will execute the injection immediately; however, if you are still defining the spec:
beforeEach(inject(function () { }));
Then it will return a function. Otherwise it would execute before your tests were to run, and not be terribly useful. This seems to just be provided as a slightly more convenient/less verbose syntax.
Related
We are using apache beam and would like to setup the logback MDC. logback MDC is a great GREAT resource when you have a request come in and you store let's say a userId (in our case, it's custId, fileId, requestId), then anytime a developer logs, it magically stamps that information on to the developers log. the developer no longer forgets to add it every log statement he adds.
I am starting in an end to end integration type test with apache beam direct runner embedded in our microservice for testing (in production, the microservice calls dataflow). currently, I am see that the MDC is good up until after the expand() methods are called. Once the processElement methods are called, the context is of course gone since I am in another thread.
So, trying to fix this piece first. Where should I put this context such that I can restore it at the beginning of this thread.
As an example, if I have an Executor.execute(runnable), then I simply transfer context using that runnable like so
public class MDCContextRunnable implements Runnable {
private final Map<String, String> mdcSnapshot;
private Runnable runnable;
public MDCContextRunnable(Runnable runnable) {
this.runnable = runnable;
mdcSnapshot = MDC.getCopyOfContextMap();
}
#Override
public void run() {
try {
MDC.setContextMap(mdcSnapshot);
runnable.run();
} Catch {
//Must log errors before mdc is cleared
log.error("message", e);. /// Logs error and MDC
} finally {
MDC.clear();
}
}
}
so I need to do the same with apache beam basically. I need to
Have a point to capture the MDC
Have a point to restore the MDC
Have a point to clear out the MDC to prevent it leaking to another request(really in case I missed something which seems to happen now and then)
Any ideas on how to do this?
oh, bonus points if it the MDC can be there when any exceptions are logged by the framework!!!! (ie. ideally, frameworks are supposed to do this for you but apache beam seems like it is not doing this. Most web frameworks have this built in).
thanks,
Dean
Based on the context and examples you gave, it sounds like you want to use MDC to automatically capture more information for your own DoFns. Your best bet for this is, depending on the lifetime you need your context available for, to use either the StartBundle/FinishBundle or Setup/Teardown methods on your DoFns to create your MDC context (see this answer for an explanation of the differences between the two). The important thing is that these methods are executed for each instance of a DoFn, meaning they will be called on the new threads created to execute these DoFns.
Under the Hood
I should explain what's happening here and how this approach differs from your original goal. The way Apache Beam executes is that your written pipeline executes on your own machine and performs pipeline construction (which is where all the expand calls are occurring). However, once a pipeline is constructed, it is sent to a runner which is often executing on a separate application unless it's the Direct Runner, and then the runner either directly executes your user code or runs it in a docker environment.
In your original approach it makes sense that you would successfully apply MDC to all logs until execution begins, because execution might not only be occurring in a different thread, but potentially also a different application or machine. However, the methods described above are executed as part of your user code, so setting up your MDC there will allow it to function on whatever thread/application/machine is executing transforms.
Just keep in mind that those methods get called for every DoFn and you will often have mutiple DoFns per thread, which is something you may need to be wary of depending on how MDC works.
I have a method:
-(void)startTaskForResult:(long long*)result {
...
}
The function I want to unit test invoke above function:
-(void)doWork {
long long result = 0;
[self startTaskForResult:&result];
}
I am using OCMock library to do unit tests. In my test case, I want to set the result argument to an mocked value e.g. 100 without care about the actual implementation of -(void)startTaskForResult:(long long*)result.
I tried the following way:
-(void)testDoWork{
// try to set 100 to argument 'result'
OCMStub([classToTest startTaskForResult:[OCMArg setToValue:OCMOCK_VALUE((long long){100})]]);
// run the function, but it doesn't use mocked value 100 for argument 'result'
[classToTest doWork];
...
}
But, when I run my test, it does't use the mocked value 100 for argument result. What is the right way to set mocked value to argument in my case then?
Few points to answer your question:
Code for your problem:
- (void)testDoWork
{
id mock = OCMPartialMock(classToTest)
OCMStub([mock startTaskForResult:[OCMArg setToValue:OCMOCK_VALUE((long long){100})]]).andForwardToRealObject;
// set your expectation here
[classToTest doWork];
}
To solve your particular problem:
Your object should be partial mock
Your method should be stubbed (you did it)
Your stub should be forwarded to real object (i assume you need method startTaskForResult: implementation to be called)
However, you face the problems because you are using wrong approach to test;
There're 3 most common strategies to write unit tests:
Arrange-Act-Assert used to test methods
Given-When-Then used to test functions
Setup-Record-Verify used to test side effects. This usually requires mocking.
So:
If you want to test that startTaskForResult: returns particular value - you should call just that and expect return value (not your case, method return type is void)
If method changes the state of object - you should expect that state change, like property value or so
If calling of doWork has a side effect of calling startTaskForResult:, you should stub it and expect it's call, almost like i've written in code above. However (!!!), however you shouldn't expect things like this. This is not a kind of behaviour that has much sense to test, because it's internal class implementation details. One possible case, when both methods are public and it's explicitly stated in class contract, that one method should call another with some preliminary setup. In this case you expect method call with some state / arguments.
To have your application code testable, you require continuously refactoring your code. Some code is untestable, it's probably better to adopt application code rather then try to cover it with tests anyway. You lose the initial goal of tests - refactoring safety and low cost of making changes.
Based on SpecFlow documentation, the [BeforeScenarioBlock] hook will be called before "Given" and "When" statement. Is there any way to make the [BeforeScenarioBlock] hook only to be called before "Given" statement ?
A [BeforeScenarioBlock] will run before any 'block' in the scenario, ie before each separate set of Given, When or Then blocks. There is no built in way to specify that a hook should only run before a particular type of block I don't think but I believe it should be straight forward enough to make sure that the code only runs before specific blocks inside the hook code. Something like this:
[BeforeScenarioBlock]
public void BeforeScenarioBlock()
{
if (ScenarioContext.Current.CurrentScenarioBlock == ScenarioBlock.Given)
{
//execute the code before the given
}
}
Although I have not tested this.
In my application, some of the Geb tests are a bit flaky since we're firing off an ajax validation http request after each form field changes. If the ajax call doesn't return fast enough, the test blows up.
I wanted to test a simple solution for this, which (rightly or wrongly, let's not get into that debate here...) is to introduce a short 100ms or so pause after each field is set, so I started looking at how & where I could make this happen.
It looks like I need to add a Thread.sleep after the NonEmptyNavigator.setInputValue and NonEmptyNavigator.setSelectValue methods are invoked. I created a subclass of GebSpec, into which I added a static initializer block:
static {
NonEmptyNavigator.metaClass.invokeMethod = { String name, args ->
def m = delegate.metaClass.getMetaMethod(name, *args)
def result = (m ? m.invoke(delegate, *args) : delegate.metaClass.invokeMissingMethod(delegate, name, args))
if ("setInputValue".equals(name) || "setSelectValue".equals(name)) {
Thread.sleep(100)
}
return result
}
}
However I added some debug logging, and I noticed that when I execute my spec I never hit this code. What am I doing wrong here...?
I know you asked not to get into a debate about putting sleeps whenever you set a form element value but I just want to assure you that this is really something you don't want to do. There are two reasons:
it will make your tests significantly slower and this will be painful in the long run as browser tests are slow in general
there will be situations (slow CI for instance) where that 100ms will not be enough, so in essence you are not removing the flakiness you are just somehow limiting it
If you really insist on doing it this way then Geb allows you to use custom Navigator implementations. Your custom non empty Navigator implementation would look like this:
class ValueSettingWaitingNonEmptyNavigator extends NonEmptyNavigator {
Navigator value(value) {
super.value(value)
Thread.sleep(100)
this
}
}
This way there's no need to monkey-patch NonEmptyNavigator and you will avoid any strange problems that might cause.
A proper solution would be to have a custom Module implementation that would override Navigator value(value) method and use waitFor() to check if the validation has completed. Finally you would wrap all your validated form elements in this module in your pages and modules content blocks. This would mean that you only wait where it's necessary and as little as possible. I don't know how big your suite is but as it will grow these 100ms will turn into minutes and you will be upset about how slow your tests are. Believe me, I've been there.
I am writing grails integration tests which call out to a controller which call a service which calls another service which calls another service.
Controller -> ServiceA.method1() -> ServiceB.method2() -> ServiceC.method3()
the last method in the last service to be called (ServiceC.method3()) makes a call to the outside world (another JVM) and returns a result, which I want to mock out for my integration test. So I am still testing the chain up to and back from that particular service method.
I was reading up on mocking in grails but it seems that it is only possible in unit testing.
Any tips how to progress this one?
Use the metaClass to override a method's functionality. I do this all the time in my integration tests as my way to mock.
So in your test method do something like this (note that the method arg types must match exactly with the real method):
controller.serviceA.serviceB.serviceC.metaClass.method3 = { Args args ->
// do whatever you want here, set flags to indicate method called,
// assert args, declare return types, etc
// return 'mocked' result
}
Make sure in your integration test tear down method you reset the metaClass of this service otherwise all your other int tests will have the same definition:
controller.serviceA.serviceB.serviceC.metaClass = null
I was reading up on mocking in grails but it seems that it is only
possible in unit testing.
That's certainly not true.
You could use all ways of mocking that are available in Groovy in both unit and integration tests.
With mocking using Map coercion, it can be this easy:
controller.serviceA.serviceB.serviceC = [method3: {return 'MockValue'}] as ServiceC