<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tips &amp; Tricks - Software Developer's Tour</title>
	<atom:link href="https://pawelmajewski.com/category/programming/tips-and-tricks/feed/" rel="self" type="application/rss+xml" />
	<link>https://pawelmajewski.com</link>
	<description>Website about programming, news in IT and more</description>
	<lastBuildDate>Wed, 11 Jun 2025 09:02:51 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>

<image>
	<url>https://pawelmajewski.com/wp-content/uploads/2024/02/logo_normal.png</url>
	<title>Tips &amp; Tricks - Software Developer's Tour</title>
	<link>https://pawelmajewski.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Background tasks in .NET application</title>
		<link>https://pawelmajewski.com/background-tasks-in-net-application/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=background-tasks-in-net-application</link>
					<comments>https://pawelmajewski.com/background-tasks-in-net-application/#comments</comments>
		
		<dc:creator><![CDATA[Paweł Majewski]]></dc:creator>
		<pubDate>Sat, 15 Feb 2025 19:41:26 +0000</pubDate>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[background tasks]]></category>
		<category><![CDATA[Hangfire]]></category>
		<guid isPermaLink="false">https://pawelmajewski.com/?p=8554</guid>

					<description><![CDATA[<p>Have you ever thought about doing something in the background to make your request shorter, but kept getting exceptions saying that the DbContext is disposed? Here is the solution https://www.hangfire.io/ Hangfire is an open-source framework for .NET that offers a straightforward approach to execute background tasks within your application. It enables the asynchronous execution of [&#8230;]</p>
<p>The post <a href="https://pawelmajewski.com/background-tasks-in-net-application/">Background tasks in .NET application</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></description>
										<content:encoded><![CDATA[<div data-elementor-type="wp-post" data-elementor-id="8554" class="elementor elementor-8554">
				<div class="elementor-element elementor-element-d2fed1b e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent" data-id="d2fed1b" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-b1cedca elementor-widget elementor-widget-heading" data-id="b1cedca" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<style>/*! elementor - v3.21.0 - 08-05-2024 */
.elementor-heading-title{padding:0;margin:0;line-height:1}.elementor-widget-heading .elementor-heading-title[class*=elementor-size-]>a{color:inherit;font-size:inherit;line-height:inherit}.elementor-widget-heading .elementor-heading-title.elementor-size-small{font-size:15px}.elementor-widget-heading .elementor-heading-title.elementor-size-medium{font-size:19px}.elementor-widget-heading .elementor-heading-title.elementor-size-large{font-size:29px}.elementor-widget-heading .elementor-heading-title.elementor-size-xl{font-size:39px}.elementor-widget-heading .elementor-heading-title.elementor-size-xxl{font-size:59px}</style><h2 class="elementor-heading-title elementor-size-default">Have you ever thought about doing something in the background to make your request shorter, but kept getting exceptions saying that the DbContext is disposed?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-03f3da4 elementor-widget elementor-widget-heading" data-id="03f3da4" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Here is the solution</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-1e2124b elementor-widget elementor-widget-text-editor" data-id="1e2124b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
			<style>/*! elementor - v3.21.0 - 08-05-2024 */
.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:#69727d;color:#fff}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap{color:#69727d;border:3px solid;background-color:transparent}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap{margin-top:8px}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap-letter{width:1em;height:1em}.elementor-widget-text-editor .elementor-drop-cap{float:left;text-align:center;line-height:1;font-size:50px}.elementor-widget-text-editor .elementor-drop-cap-letter{display:inline-block}</style>				<p><a title="Hangfire" href="https://www.hangfire.io/" target="_blank" rel="noopener">https://www.hangfire.io/</a></p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-fd3beda e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent" data-id="fd3beda" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-15e1c8d elementor-widget elementor-widget-text-editor" data-id="15e1c8d" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Hangfire is an open-source framework for .NET that offers a straightforward approach to execute background tasks within your application. It enables the asynchronous execution of jobs and the ability to schedule them to run either at a designated time or on a recurring basis.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-1d78958 elementor-widget elementor-widget-text-editor" data-id="1d78958" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Firstly, install the following nuget packages</p><p><a href="https://www.nuget.org/packages/Hangfire" target="_blank" rel="noopener">Hangfire</a></p><p><a style="text-align: var(--text-align); background-color: #ffffff;" href="https://www.nuget.org/packages/Hangfire.Core/" target="_blank" rel="noopener">Hangfire.Core</a></p><p><a href="https://www.nuget.org/packages/Hangfire.SqlServer/" target="_blank" rel="noopener"><span style="text-align: var(--text-align);">Hangfire.SqlServer</span></a></p><p><a href="https://www.nuget.org/packages/Microsoft.Data.SqlClient" target="_blank" rel="noopener">Microsoft.Data.SqlClient</a></p>						</div>
				</div>
				<div class="elementor-element elementor-element-dfe10b7 elementor-widget elementor-widget-image" data-id="dfe10b7" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
			<style>/*! elementor - v3.21.0 - 08-05-2024 */
.elementor-widget-image{text-align:center}.elementor-widget-image a{display:inline-block}.elementor-widget-image a img[src$=".svg"]{width:48px}.elementor-widget-image img{vertical-align:middle;display:inline-block}</style>										<img loading="lazy" decoding="async" loading="lazy" width="1024" height="376" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h58_57-1024x376.png" class="attachment-large size-large wp-image-8557" alt="installed nuget packages" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h58_57-1024x376.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h58_57-300x110.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h58_57-768x282.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h58_57.png 1312w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-a1068c8 elementor-widget elementor-widget-text-editor" data-id="a1068c8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Then configuration, I assume you are at least junior .NET devleoper and know basic configuration in Program.cs</p>						</div>
				</div>
				<div class="elementor-element elementor-element-7e3de8f elementor-widget elementor-widget-code-block-for-elementor" data-id="7e3de8f" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>public interface IFakeEmailSenderBackgroundJob
{
    Task Send(string message, string title, string destinationEmail);
}

public class FakeEmailSenderBackgroundJob : IFakeEmailSenderBackgroundJob
{
    public async Task Send(string message, string title, string destinationEmail)
    {
        await File.WriteAllTextAsync($&quot;mails.txt&quot;, $&quot;{title}\t{message}\t{destinationEmail}\n&quot;);
    }
}</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-c612ed1 elementor-widget elementor-widget-text-editor" data-id="c612ed1" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>I&#8217;ve created simple fake email sender which is saving to file sent mails.</p><p>Create SQL Server database named &#8220;Hangfire-db&#8221;, and then add the following configuration</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d82bc0a elementor-widget elementor-widget-code-block-for-elementor" data-id="d82bc0a" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>builder.Services.AddHangfire(x =&gt;
            x.UseSqlServerStorage(&quot;Data Source=localhost;Initial Catalog=Hangfire-db;Integrated Security=true;TrustServerCertificate=true;&quot;));
builder.Services.AddHangfireServer();
builder.Services.AddScoped&lt;IFakeEmailSenderBackgroundJob, FakeEmailSenderBackgroundJob&gt;();</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-8e8a164 elementor-widget elementor-widget-text-editor" data-id="8e8a164" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>in the app section</p>						</div>
				</div>
				<div class="elementor-element elementor-element-b56cd60 elementor-widget elementor-widget-code-block-for-elementor" data-id="b56cd60" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>app.UseHangfireDashboard();</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-0121998 elementor-widget elementor-widget-text-editor" data-id="0121998" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>It&#8217;s web api project, so let&#8217;s create sample endpoint which will be using our FakeEmailSenderBackgroundJob</p>						</div>
				</div>
				<div class="elementor-element elementor-element-71e319a elementor-widget elementor-widget-code-block-for-elementor" data-id="71e319a" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>app.MapPost(&quot;/send-mail&quot;, (string message, string title, string destinationEmail) =&gt;
{
    return BackgroundJob.Schedule&lt;IFakeEmailSenderBackgroundJob&gt;(x =&gt;
            x.Send(message, title, destinationEmail),
            DateTimeOffset.Now.AddMinutes(1)
        );
})
.WithName(&quot;SendMail&quot;)
.WithOpenApi();</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-fc453e2 elementor-widget elementor-widget-text-editor" data-id="fc453e2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>As you can understand from this code, the endpoint will schedule the sending of the email to occur one minute after the endpoint is executed.</p><p>You can go to the <strong>/hangfire</strong> url in your application and then you should see Hangfire dashboard.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-7245d1b elementor-widget elementor-widget-image" data-id="7245d1b" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h32_17-1024x525.png" class="attachment-large size-large wp-image-8558" alt="Hangfire dashboard" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h32_17-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h32_17-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h32_17-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h32_17-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h32_17-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_21h32_17-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-a9c7659 elementor-widget elementor-widget-image" data-id="a9c7659" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="842" height="348" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h11_55.png" class="attachment-large size-large wp-image-8559" alt="" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h11_55.png 842w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h11_55-300x124.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h11_55-768x317.png 768w" sizes="auto, (max-width: 842px) 100vw, 842px" />													</div>
				</div>
				<div class="elementor-element elementor-element-b96f54e elementor-widget elementor-widget-text-editor" data-id="b96f54e" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Send two requests and see what happens.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-cb936a9 elementor-widget elementor-widget-image" data-id="cb936a9" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="784" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h13_40-1024x784.png" class="attachment-large size-large wp-image-8560" alt="request swagger" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h13_40-1024x784.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h13_40-300x230.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h13_40-768x588.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h13_40.png 1310w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-eb993bf elementor-widget elementor-widget-image" data-id="eb993bf" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="847" height="357" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_03.png" class="attachment-large size-large wp-image-8561" alt="scheduled job hangfire" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_03.png 847w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_03-300x126.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_03-768x324.png 768w" sizes="auto, (max-width: 847px) 100vw, 847px" />													</div>
				</div>
				<div class="elementor-element elementor-element-0be9bf7 elementor-widget elementor-widget-text-editor" data-id="0be9bf7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>We can see that our job is scheduled correctly</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d13c3c5 elementor-widget elementor-widget-image" data-id="d13c3c5" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="251" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_15-1024x251.png" class="attachment-large size-large wp-image-8562" alt="scheduled job hangfire details" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_15-1024x251.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_15-300x74.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_15-768x189.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_15-1536x377.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h15_15-2048x503.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-fa8971b elementor-widget elementor-widget-text-editor" data-id="fa8971b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Here are the details regarding our enqueued job.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-9be39e7 elementor-widget elementor-widget-text-editor" data-id="9be39e7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Wait for a one minute.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-752a3a0 elementor-widget elementor-widget-image" data-id="752a3a0" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_19-1024x525.png" class="attachment-large size-large wp-image-8566" alt="hangfire job successed" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_19-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_19-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_19-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_19-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_19-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_19-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-c765884 elementor-widget elementor-widget-image" data-id="c765884" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="772" height="430" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_36.png" class="attachment-large size-large wp-image-8567" alt="" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_36.png 772w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_36-300x167.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_36-768x428.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h16_36-770x430.png 770w" sizes="auto, (max-width: 772px) 100vw, 772px" />													</div>
				</div>
				<div class="elementor-element elementor-element-d9f12f4 elementor-widget elementor-widget-text-editor" data-id="d9f12f4" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>The enqueued job has been executed, and as we can see, the result is correct. You can perform any desired operations inside your job class. As mentioned earlier regarding the disposed DbContext, you can inject your DbContext or repository directly into the job class.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-e1771a7 elementor-widget elementor-widget-heading" data-id="e1771a7" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">How about failed tasks?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-f6dee44 elementor-widget elementor-widget-text-editor" data-id="f6dee44" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Let&#8217;s change the implementation of the <strong>FakeEmailSenderBackgroundJob </strong>to the following</p>						</div>
				</div>
				<div class="elementor-element elementor-element-6bd3b30 elementor-widget elementor-widget-code-block-for-elementor" data-id="6bd3b30" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>public class FakeEmailSenderBackgroundJob : IFakeEmailSenderBackgroundJob
{
    public async Task Send(string message, string title, string destinationEmail)
    {
        throw new Exception();
        await File.WriteAllTextAsync($&quot;mails.txt&quot;, $&quot;{title}\t{message}\t{destinationEmail}\n&quot;);
    }
}</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-c681a6b elementor-widget elementor-widget-text-editor" data-id="c681a6b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Let&#8217;s check our dashboard now.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-8f69651 elementor-widget elementor-widget-image" data-id="8f69651" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="670" height="337" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h27_57.png" class="attachment-large size-large wp-image-8571" alt="failed queue empty" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h27_57.png 670w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h27_57-300x151.png 300w" sizes="auto, (max-width: 670px) 100vw, 670px" />													</div>
				</div>
				<div class="elementor-element elementor-element-107f149 elementor-widget elementor-widget-text-editor" data-id="107f149" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Let&#8217;s wait a minute and check again.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-2bf3d8d elementor-widget elementor-widget-image" data-id="2bf3d8d" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h30_38-1024x525.png" class="attachment-large size-large wp-image-8572" alt="hangfire retry" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h30_38-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h30_38-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h30_38-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h30_38-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h30_38-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_22h30_38-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-9caabbd elementor-widget elementor-widget-text-editor" data-id="9caabbd" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Here&#8217;s an interesting observation: the Hangfire job failed to complete successfully and raised an exception, resulting in the job being requeued. Hangfire attempted to execute the job again, with the default behavior allowing for 10 attempts.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-f4e3df1 elementor-widget elementor-widget-text-editor" data-id="f4e3df1" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>We can read number of attempts from information container with blue background</p>						</div>
				</div>
				<div class="elementor-element elementor-element-7827979 elementor-alert-info elementor-widget elementor-widget-alert" data-id="7827979" data-element_type="widget" data-widget_type="alert.default">
				<div class="elementor-widget-container">
			<style>/*! elementor - v3.21.0 - 08-05-2024 */
.elementor-alert{padding:15px;border-left:5px solid transparent;position:relative;text-align:start}.elementor-alert .elementor-alert-title{display:block;font-weight:700}.elementor-alert .elementor-alert-description{font-size:13px}.elementor-alert button.elementor-alert-dismiss{position:absolute;right:var(--dismiss-icon-horizontal-position,10px);top:var(--dismiss-icon-vertical-position,10px);padding:3px;font-size:var(--dismiss-icon-size,20px);line-height:1;background:transparent;color:var(--dismiss-icon-normal-color,inherit);border:none;cursor:pointer;transition-duration:var(--dismiss-icon-hover-transition-duration,.3s)}.elementor-alert button.elementor-alert-dismiss:hover{color:var(--dismiss-icon-hover-color,inherit)}.elementor-alert button.elementor-alert-dismiss svg{width:var(--dismiss-icon-size,20px);height:var(--dismiss-icon-size,20px);fill:var(--dismiss-icon-normal-color,currentColor);transition-duration:var(--dismiss-icon-hover-transition-duration,.3s)}.elementor-alert button.elementor-alert-dismiss svg:hover{fill:var(--dismiss-icon-hover-color,currentColor)}.elementor-alert-info .elementor-alert{color:#31708f;background-color:#d9edf7;border-color:#bcdff1}.elementor-alert-success .elementor-alert{color:#3c763d;background-color:#dff0d8;border-color:#cae6be}.elementor-alert-warning .elementor-alert{color:#8a6d3b;background-color:#fcf8e3;border-color:#f9f0c3}.elementor-alert-danger .elementor-alert{color:#a94442;background-color:#f2dede;border-color:#e8c4c4}@media (max-width:767px){.elementor-alert{padding:10px}.elementor-alert button.elementor-alert-dismiss{right:7px;top:7px}}</style>		<div class="elementor-alert" role="alert">

						<span class="elementor-alert-title">Scheduled</span>
			
						<span class="elementor-alert-description">Retry attempt 5 of 10: Exception of type 'System.Exception' was thrown.</span>
			
			
		</div>
				</div>
				</div>
				<div class="elementor-element elementor-element-779f1e2 elementor-widget elementor-widget-image" data-id="779f1e2" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_27-1024x525.png" class="attachment-large size-large wp-image-8585" alt="job failed" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_27-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_27-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_27-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_27-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_27-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_27-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-b324082 elementor-widget elementor-widget-text-editor" data-id="b324082" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>As you can see, Hangfire attempted to execute its job 10 times before marking it as <strong>Failed</strong>.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-04d1eb5 elementor-widget elementor-widget-text-editor" data-id="04d1eb5" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Below you can see failed jobs tab</p>						</div>
				</div>
				<div class="elementor-element elementor-element-b54b411 elementor-widget elementor-widget-image" data-id="b54b411" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_06-1024x525.png" class="attachment-large size-large wp-image-8586" alt="failed jobs tab" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_06-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_06-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_06-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_06-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_06-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-17_23h37_06-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-b456da5 elementor-widget elementor-widget-heading" data-id="b456da5" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">What else Hangfire can do?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-2bf512f elementor-widget elementor-widget-text-editor" data-id="2bf512f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><strong>Fire-and-Forget Jobs</strong> &#8211; This job is executed immediately after we execute our method associated with it. Background jobs are useful when you have a large task that consumes a lot of time, and it&#8217;s better to perform it asynchronously in the background.</p><p><strong>Recurring Jobs</strong> &#8211; We can set up a <a href="https://en.wikipedia.org/wiki/Cron" target="_blank" rel="noopener">cron expression</a> to determine when tasks will be triggered. This is useful, for example, in a SaaS application where we need to check daily if a user has a valid subscription, and if not, suspend it. Similarly, in an application for lawyers, we might want to display court dates with deadlines 10 days in advance. In this case, it&#8217;s beneficial to have a background job executed daily that marks important cases. These are just a few examples; there are many other situations where a recurring job would be useful.</p><p><strong>Delayed Jobs </strong>&#8211; We used it in our example. You can set a DateTimeOffset with a delay after which the task will be processed.</p><p><strong>Continuations </strong>&#8211; We can execute a job when its parent job finishes. This is useful when we want to create a pipeline of task execution, especially when certain data needs to be created or prepared beforehand.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-3ae84f6 elementor-widget elementor-widget-text-editor" data-id="3ae84f6" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Hangfire has more paid options, but I don&#8217;t think they are necessary for standard purposes</p>						</div>
				</div>
					</div>
				</div>
				</div><p>The post <a href="https://pawelmajewski.com/background-tasks-in-net-application/">Background tasks in .NET application</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://pawelmajewski.com/background-tasks-in-net-application/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>How to test email sending service?</title>
		<link>https://pawelmajewski.com/how-to-test-email-sending-service/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-test-email-sending-service</link>
					<comments>https://pawelmajewski.com/how-to-test-email-sending-service/#respond</comments>
		
		<dc:creator><![CDATA[Paweł Majewski]]></dc:creator>
		<pubDate>Thu, 16 Jan 2025 06:30:00 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[mailtrap]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://pawelmajewski.com/?p=8435</guid>

					<description><![CDATA[<p>Testing email templates, whether for existing features or new features, is a common task performed by testers during the testing process. There are many ways to manage sending emails on different environments: &#8211; Development &#8211; Testing &#8211; Staging &#8211; Production You have to consider how your application should behave in all of these environments. How [&#8230;]</p>
<p>The post <a href="https://pawelmajewski.com/how-to-test-email-sending-service/">How to test email sending service?</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></description>
										<content:encoded><![CDATA[<div data-elementor-type="wp-post" data-elementor-id="8435" class="elementor elementor-8435">
				<div class="elementor-element elementor-element-c43f8d6 e-con-full e-flex wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent" data-id="c43f8d6" data-element_type="container">
				<div class="elementor-element elementor-element-beb1f63 elementor-widget elementor-widget-text-editor" data-id="beb1f63" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Testing email templates, whether for existing features or new features, is a common task performed by testers during the testing process. There are many ways to manage sending emails on different environments:</p><ul><li><span style="text-align: var(--text-align);">&#8211; Development</span></li><li>&#8211; Testing</li><li>&#8211; Staging</li><li>&#8211; Production</li></ul><p>You have to consider how your application should behave in all of these environments.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-82d79fe elementor-widget elementor-widget-heading" data-id="82d79fe" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">How companies deal with this problem?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-09a93b8 elementor-widget elementor-widget-text-editor" data-id="09a93b8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>First, and in my opinion, the worst case scenario occurs when the development team decides to add special logic to their EmailService, redirecting all emails to a specific email address, or when we allow sending emails to workers within our organization.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d1639c6 elementor-widget elementor-widget-image" data-id="d1639c6" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="803" src="https://pawelmajewski.com/wp-content/uploads/2024/02/01_email_service_replace_dest_email-1-1024x803.png" class="attachment-large size-large wp-image-8440" alt="01_email_service_replace_dest_email" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/01_email_service_replace_dest_email-1-1024x803.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/01_email_service_replace_dest_email-1-300x235.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/01_email_service_replace_dest_email-1-768x603.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/01_email_service_replace_dest_email-1-1536x1205.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/01_email_service_replace_dest_email-1.png 1680w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-370092f elementor-widget elementor-widget-text-editor" data-id="370092f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>It shouldn&#8217;t pass code review.</p><p>This is the worst possible option for resolving this problem. This code cannot be tested to ensure that the application works correctly at the current time.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-e3763e0 elementor-widget elementor-widget-image" data-id="e3763e0" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="700" src="https://pawelmajewski.com/wp-content/uploads/2024/02/02_email_with_different_implementations_for_each_env-1024x700.png" class="attachment-large size-large wp-image-8439" alt="02_email_with_different_implementations_for_each_env" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/02_email_with_different_implementations_for_each_env-1024x700.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/02_email_with_different_implementations_for_each_env-300x205.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/02_email_with_different_implementations_for_each_env-768x525.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/02_email_with_different_implementations_for_each_env.png 1372w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-5b8c496 elementor-widget elementor-widget-text-editor" data-id="5b8c496" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>In this code, we have separated the logic for each environment, so there is no need for conditional statements (&#8216;if&#8217; statements) in the implementation types.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-c0f4e87 elementor-widget elementor-widget-text-editor" data-id="c0f4e87" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>However, this version is also not as good as it could be.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-7d290cc elementor-widget elementor-widget-text-editor" data-id="7d290cc" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><b>Emails used for testing purposes should not be sent outside of the organization&#8217;s infrastructure.</b></p>						</div>
				</div>
				<div class="elementor-element elementor-element-30ba404 elementor-widget elementor-widget-text-editor" data-id="30ba404" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>So let&#8217;s go further.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-6db1d2c elementor-widget elementor-widget-heading" data-id="6db1d2c" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">What should we do to make this code look nice?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-e830895 elementor-widget elementor-widget-text-editor" data-id="e830895" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>First of all, in the perfect case we have no &#8216;if&#8217; statements in our code. It&#8217;s possible to do with several ways. I&#8217;ll talk here about <b>2 different ways</b> to achieve this goal but without code.</p><p>What should it look like?</p><p>We should only change credentials stored in .NET web applications&#8217; <strong><a href="https://learn.microsoft.com/en-us/iis-administration/configuration/appsettings.json" target="_blank" rel="noopener">appsettings.json</a> </strong>files<strong>.</strong> Different environment credentials should be stored in different files. In the best-case scenario, only the developer&#8217;s credentials should be stored directly, while all other credentials should be stored in either <a href="https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-8.0&amp;tabs=windows" target="_blank" rel="noopener">dotnet secrets</a> or <a href="https://azure.microsoft.com/en-us/products/key-vault" target="_blank" rel="noopener">Azure Key Vault</a></p>						</div>
				</div>
				<div class="elementor-element elementor-element-1aae33d elementor-widget elementor-widget-heading" data-id="1aae33d" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">1. Create Fake SMTP Server </h2>		</div>
				</div>
				<div class="elementor-element elementor-element-1e60e34 elementor-widget elementor-widget-text-editor" data-id="1e60e34" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>It&#8217;s a good option when we want to keep everything within our private infrastructure, which is very important for large organizations.</p><p>For development purposes, we have credentials for a Fake SMTP Server, and the code itself does not change.</p><p><strong>How should work Fake SMTP Server?</strong></p><p>The Fake SMTP Server should receive the same data as a real SMTP Server as input, but instead of sending it, it should save the data to a database. Additionally, it should provide a public interface (for example, a web frontend) to search for emails.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-5f72bae elementor-widget elementor-widget-heading" data-id="5f72bae" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">2. Use Fake SMTP Server as a Service</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-bd25338 elementor-view-default elementor-position-top elementor-mobile-position-top elementor-widget elementor-widget-icon-box" data-id="bd25338" data-element_type="widget" data-widget_type="icon-box.default">
				<div class="elementor-widget-container">
			<link rel="stylesheet" href="https://pawelmajewski.com/wp-content/plugins/elementor/assets/css/widget-icon-box.min.css">		<div class="elementor-icon-box-wrapper">

						<div class="elementor-icon-box-icon">
				<span  class="elementor-icon elementor-animation-">
				<svg aria-hidden="true" class="e-font-icon-svg e-fas-exclamation" viewBox="0 0 192 512" xmlns="http://www.w3.org/2000/svg"><path d="M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"></path></svg>				</span>
			</div>
			
						<div class="elementor-icon-box-content">

									<h3 class="elementor-icon-box-title">
						<span  >
							INFORMATION						</span>
					</h3>
				
									<p class="elementor-icon-box-description">
						I would like to emphasize that I don't have a partnership with any company and the indication of a specific service is only because I had the opportunity to use it in commercial project.					</p>
				
			</div>
			
		</div>
				</div>
				</div>
				<div class="elementor-element elementor-element-40d2c14 elementor-widget-divider--separator-type-pattern elementor-widget-divider--no-spacing elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="40d2c14" data-element_type="widget" data-widget_type="divider.default">
				<div class="elementor-widget-container">
			<style>/*! elementor - v3.21.0 - 08-05-2024 */
.elementor-widget-divider{--divider-border-style:none;--divider-border-width:1px;--divider-color:#0c0d0e;--divider-icon-size:20px;--divider-element-spacing:10px;--divider-pattern-height:24px;--divider-pattern-size:20px;--divider-pattern-url:none;--divider-pattern-repeat:repeat-x}.elementor-widget-divider .elementor-divider{display:flex}.elementor-widget-divider .elementor-divider__text{font-size:15px;line-height:1;max-width:95%}.elementor-widget-divider .elementor-divider__element{margin:0 var(--divider-element-spacing);flex-shrink:0}.elementor-widget-divider .elementor-icon{font-size:var(--divider-icon-size)}.elementor-widget-divider .elementor-divider-separator{display:flex;margin:0;direction:ltr}.elementor-widget-divider--view-line_icon .elementor-divider-separator,.elementor-widget-divider--view-line_text .elementor-divider-separator{align-items:center}.elementor-widget-divider--view-line_icon .elementor-divider-separator:after,.elementor-widget-divider--view-line_icon .elementor-divider-separator:before,.elementor-widget-divider--view-line_text .elementor-divider-separator:after,.elementor-widget-divider--view-line_text .elementor-divider-separator:before{display:block;content:"";border-block-end:0;flex-grow:1;border-block-start:var(--divider-border-width) var(--divider-border-style) var(--divider-color)}.elementor-widget-divider--element-align-left .elementor-divider .elementor-divider-separator>.elementor-divider__svg:first-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-left .elementor-divider-separator:before{content:none}.elementor-widget-divider--element-align-left .elementor-divider__element{margin-left:0}.elementor-widget-divider--element-align-right .elementor-divider .elementor-divider-separator>.elementor-divider__svg:last-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-right .elementor-divider-separator:after{content:none}.elementor-widget-divider--element-align-right .elementor-divider__element{margin-right:0}.elementor-widget-divider--element-align-start .elementor-divider .elementor-divider-separator>.elementor-divider__svg:first-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-start .elementor-divider-separator:before{content:none}.elementor-widget-divider--element-align-start .elementor-divider__element{margin-inline-start:0}.elementor-widget-divider--element-align-end .elementor-divider .elementor-divider-separator>.elementor-divider__svg:last-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-end .elementor-divider-separator:after{content:none}.elementor-widget-divider--element-align-end .elementor-divider__element{margin-inline-end:0}.elementor-widget-divider:not(.elementor-widget-divider--view-line_text):not(.elementor-widget-divider--view-line_icon) .elementor-divider-separator{border-block-start:var(--divider-border-width) var(--divider-border-style) var(--divider-color)}.elementor-widget-divider--separator-type-pattern{--divider-border-style:none}.elementor-widget-divider--separator-type-pattern.elementor-widget-divider--view-line .elementor-divider-separator,.elementor-widget-divider--separator-type-pattern:not(.elementor-widget-divider--view-line) .elementor-divider-separator:after,.elementor-widget-divider--separator-type-pattern:not(.elementor-widget-divider--view-line) .elementor-divider-separator:before,.elementor-widget-divider--separator-type-pattern:not([class*=elementor-widget-divider--view]) .elementor-divider-separator{width:100%;min-height:var(--divider-pattern-height);-webkit-mask-size:var(--divider-pattern-size) 100%;mask-size:var(--divider-pattern-size) 100%;-webkit-mask-repeat:var(--divider-pattern-repeat);mask-repeat:var(--divider-pattern-repeat);background-color:var(--divider-color);-webkit-mask-image:var(--divider-pattern-url);mask-image:var(--divider-pattern-url)}.elementor-widget-divider--no-spacing{--divider-pattern-size:auto}.elementor-widget-divider--bg-round{--divider-pattern-repeat:round}.rtl .elementor-widget-divider .elementor-divider__text{direction:rtl}.e-con-inner>.elementor-widget-divider,.e-con>.elementor-widget-divider{width:var(--container-widget-width,100%);--flex-grow:var(--container-widget-flex-grow)}</style>		<div class="elementor-divider" style="--divider-pattern-url: url(&quot;data:image/svg+xml,%3Csvg xmlns=&#039;http://www.w3.org/2000/svg&#039; preserveAspectRatio=&#039;xMidYMid meet&#039; overflow=&#039;visible&#039; height=&#039;100%&#039; viewBox=&#039;0 0 120 26&#039; fill=&#039;black&#039; stroke=&#039;none&#039;%3E%3Cpolygon points=&#039;0,14.4 0,21 11.5,12.4 21.3,20 30.4,11.1 40.3,20 51,12.4 60.6,20 69.6,11.1 79.3,20 90.1,12.4 99.6,20 109.7,11.1 120,21 120,14.4 109.7,5 99.6,13 90.1,5 79.3,14.5 71,5.7 60.6,12.4 51,5 40.3,14.5 31.1,5 21.3,13 11.5,5 	&#039;/%3E%3C/svg%3E&quot;);">
			<span class="elementor-divider-separator">
						</span>
		</div>
				</div>
				</div>
				<div class="elementor-element elementor-element-0a12774 elementor-widget elementor-widget-image" data-id="0a12774" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
										<figure class="wp-caption">
											<a href="https://mailtrap.io/" target="_blank">
							<img loading="lazy" decoding="async" loading="lazy" width="1024" height="761" src="https://pawelmajewski.com/wp-content/uploads/2024/02/mailtrap-1024x761.png" class="attachment-large size-large wp-image-8441" alt="mailtrap" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/mailtrap-1024x761.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/mailtrap-300x223.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/mailtrap-768x571.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/mailtrap.png 1334w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />								</a>
											<figcaption class="widget-image-caption wp-caption-text">https://mailtrap.io/</figcaption>
										</figure>
							</div>
				</div>
				<div class="elementor-element elementor-element-e1c9163 elementor-widget elementor-widget-text-editor" data-id="e1c9163" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><a href="https://mailtrap.io/" target="_blank" rel="noopener sponsored">Mailtrap</a> is an easy-to-use platform for sending real and test emails from our applications. I&#8217;ve only tested the Email Testing feature, so I&#8217;ll mainly focus on it.</p><p>Mailtrap offers a clear web interface to read all sent emails.</p><p><strong>What makes this product stand out?</strong> </p><p>Testers can view all emails sent from the application. When they analyze test cases that have been tested by others, they can also verify emails.</p>						</div>
				</div>
				</div>
				</div><p>The post <a href="https://pawelmajewski.com/how-to-test-email-sending-service/">How to test email sending service?</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://pawelmajewski.com/how-to-test-email-sending-service/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
