-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add interface on TelemetryClient #342
Comments
We would typically initialize TelemetryClient with the test channel like this. Which methods would you prefer to have in interface - high level like |
I have both use cases: replacing the client to avoid a network dependency and verify the telemetry It looks like StubTelemetryChannel solves both cases. Then I am happy and don't really need the interface. |
@ogborstad I'm glad it is working for you. We still thinking what would be the best way to enable easy testing of telemetry client and use it with the DI. Thanks for asking! |
@SergeyKanzhelev Is there any update here? Did the team decide not have an interface at all? I believe having an Interface can help easily mock (use other advanced features) that most of the testing frameworks like Moq provide. Creating a |
@GiriB for now we will proceed with the mock channel. Since there is no reason |
@SergeyKanzhelev what sort of confusion are you referring to? My team would very much benefit from having an interface for TelemetryClient so that we can use Moq to verify we are passing the correct dimensions to a metric. Yes, it is possible to do this today without Moq, but it is much more code than it needs to be. |
…343) * Add tests to illustrate issue #342 * Fix issue #342 * Incorporate review feedback: Set timestamp in OnBeginRequest. Add a test for issue #340 Set Id instead of OperationId (Fixes #340) * Add test for issue #333 * Implement OperationCorrelationTelemetryInitializer Fixes issue #333 * Use UTC for start time epoch * Use Start()/Stop() extension methods
@SergeyKanzhelev Your example of the stubbed telemetry channel involves using the TelemetryClient's constructor which is marked obsolete. Would be nice to have a mocked instance of TelemetryClient without all the compiler warnings that come with it today. |
@SergeyKanzhelev Yes, please reconsider. ^^^ Simply asking that the TelemetryClient implement an ITelemetryClient so we can verify the TrackMetric calls. That is the right level for us to verify. Our prod code knows nothing whatsoever about ITelemetryChannels, it would be weird if its unit tests had to. Doing so in effect makes the TelemetryClient part of the unit being unit tested, and that is of no interest to us. |
Is there any updates on this? It seems to me that |
@TimothyMothra @cijothomas @lmolkova @SergeyKanzhelev could one of you reopen this issue please? The TelemetryClient should support an interface to make it nice and easy to mock out. I never yet wrote a unit test that wanted to cover the App Insights SDK code. |
I'll reopen the issue for further consideration. |
cc: @rajkumar-rangaraj as Raj will be working on ApplicationInsights/OpenTelemetry integrations. |
Do you have any update to share about this issue ? has it been shipped in any version (released or preview) ? |
No update. No work is done on changing this so far. |
Why is it so difficult to add an interface and make a lot of developers happy? This item is open for almost 5 years and still actual. |
Can someone at least put a link to StubTelemetryChannel? It would make this a lot easier |
Hi all, Then you can inject an Enjoy. Github Link: NuGet: |
Where is this feature? We just need to verify TrackEvent() was called but can't do this currently |
The real confusing part the funky stub and that we need this GitHub issue to find the stub code/tricks Anyway, is a Pull Request accepted? By the way, this is the 3rd most updated issue. See Issues sorted by upvote - and it seems that number 2 is already fixed - so it's 2 |
Adding yet another comment in support of this. This would be super useful! We just want to be able to verify that the right method from the TelemetryClient is called with the expected parameters. Don't really want to introduce a unofficial third party library to wrap it or need to code a custom wrapper, just for testing. Is this going to be re-considered please? |
Found myself again in a position where I simply needed to mock a telemetry client to pass in a dependency to satisfy the constructor when the tests themselves couldn't care about the telemetry itself. Beating the drum for this long-standing request to be solved officially. |
Same here. It can't be that hard to add this Interface. It would make developers live much easier. Do we need wait five more years? |
Instead of an interface, here's a complete example using a stub telemetry channel. I've kept everything in one file and eliminated some blank lines, just for exposition purposes. using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System.Collections.Concurrent;
using Xunit;
namespace TestProject1
{
public class UnitTest1
{
private ConcurrentQueue<ITelemetry> TelemetryItems { get; } = new ConcurrentQueue<ITelemetry>();
[Fact]
public void Test1()
{
var telemetryClient = CreateMockTelemetryClient();
var componentUnderTest = new ComponentUnderTest(telemetryClient);
componentUnderTest.Test();
Assert.True(TelemetryItems.TryDequeue(out ITelemetry? first));
Assert.IsType<RequestTelemetry>(first);
Assert.Equal("ItWorks", ((RequestTelemetry)first!).Name);
}
private TelemetryClient CreateMockTelemetryClient()
{
var telemetryConfiguration = new TelemetryConfiguration
{
ConnectionString = "InstrumentationKey=" + Guid.NewGuid().ToString(),
TelemetryChannel = new StubTelemetryChannel(TelemetryItems.Enqueue)
};
// TODO: Add telemetry initializers and processors if/as necessary.
return new TelemetryClient(telemetryConfiguration);
}
}
/// <summary>
/// A telemetry channel that simply calls a delegate.
/// </summary>
internal sealed class StubTelemetryChannel : ITelemetryChannel
{
private readonly Action<ITelemetry> _onSend;
public StubTelemetryChannel(Action<ITelemetry> onSend) => _onSend = onSend ?? throw new ArgumentNullException(nameof(onSend));
public bool? DeveloperMode { get; set; }
public string EndpointAddress { get; set; } = "";
public void Dispose() { }
public void Flush() { }
public void Send(ITelemetry item) => _onSend(item);
}
internal class ComponentUnderTest
{
private TelemetryClient _telemetryClient;
public ComponentUnderTest(TelemetryClient telemetryClient) => _telemetryClient = telemetryClient;
public void Test()
{
using var operation = _telemetryClient.StartOperation<RequestTelemetry>("ItWorks");
// TODO: Body of test
}
}
} The interesting parts here are:
Obviously, all of this can be customized as appropriate for your application and testing environment. |
FYI There is an excellent pr here: Unfortunately there is no (usefull) response why it isn't getting merged. |
I wish TelemetryClient implemented an interface so that it would be easier to switch the client in automated tests
The text was updated successfully, but these errors were encountered: